当前位置: 首页 > 后端技术 > PHP

Go1.20arena可以手动管理内存,如何使用?

时间:2023-03-29 22:41:27 PHP

大家好,我是炸鱼。Go1.20中的手动内存管理最近引起了很多关注。众所周知,Go是一门带有垃圾回收(GC)的编程语言,可以自动进行内存申请、释放等内存操作。有了GC,可以简化编程的心理成本,也可以保证内存的安全。当我们说“一般”时,我们的意思是有例外。人们说六个,通常有七个。Go的异常出现了。Go1.20arena新版本Go1.20,根据谷歌自身需求,快速通过实践,正式支持arena,可实现手动内存管理(目前为实验特性)。现在可以通过GOEXPERIMENT=arenas环境变量启用:GOEXPERIMENT=arenasgorunmain.go这个特性允许程序员从连续的内存区域中手动申请分配一组内存对象,也可以一次性全部释放.关键是可以手动管理内存。提供了arenaAPINewArena:创建一个新的arena内存空间。释放:释放竞技场及其关联的对象。新建:基于竞技场,新建对象。MakeSlice:基于arena,创建新的slice。Clone:克隆一个arena对象并移动到内存堆中。一些arena示例下面的案例和性能测试是基于golangmemoryarenas[101guide]中uptrace分享的arena示例,此处引用,不自己创建。非常适合初学者当demo使用,打算自己留着,下次用的时候加倍使用。arena.NewArena让我们快速开始。代码如下:import"arena"typeTstruct{FoostringBar[16]byte}funcprocessRequest(req*http.Request){//在函数开头创建一个arenamem:=arena.NewArena()//在函数releasearenadefermem.Free()的末尾//从已应用的arena中申请一些对象fori:=0;我<10;i++{obj:=arena.New[T](mem"T")}//从应用的arena中申请一个切片对象(指定长度和容量)slice:=arena.MakeSlice[T](mem,100,200"T")}arena.Clone如果你想单独使用一个应用对象。可以在Clone方法的帮助下单独处理。以下代码://创建一个arena:=arena.NewArena()obj1:=arena.New[T](mem"T")//分配一个arena对象obj2:=arena.Clone(obj1)//复制一个arena将内存堆上的对象移动到内存堆中fmt.Println(obj2==obj1)//即使是基于复制,两者也不完全等价//释放arena,obj1不能用,obj2可以通常使用mem.Free()释放最早请求的arena,这里的Clone方法会将obj1复制到一个新的内存堆中,然后赋值给obj2。后续单独使用obj2可以继续使用。reflect.ArenaNew也可以与arena和reflect标准库结合使用。以下代码:vartyp=reflect.TypeOf((*T)(nil)).Elem()mem:=arena.NewArena()defermem.Free()value:=reflect.ArenaNew(mem,typ)fmt。println(value.Interface().(*T))arena.MakeSlice该方法的一般用法:arena.MakeSlice[string](mem,length,capacity"string")如果需要申请一个新的slice,添加elements:slice:=arena.MakeSlice[string](mem,0,0"string")slice=append(slice,"")需要注意的是arena目前不支持map。但是您可以使用泛型实现类似的效果。arena.Stringarena原则上不支持string。但是我们还是可以通过unsafe.String方法的骚操作来变相的实现。代码如下:src:="我的大脑在煎鱼"mem:=arena.NewArena()defermem.Free()bs:=arena.MakeSlice[byte](mem,len(src"byte"),len(src))copy(bs,src)str:=unsafe.String(&bs[0],len(bs))申请的arena释放后,对应的字符串就不能使用了,需要特别注意。Performancearena允许手动内存管理的特性来自于内部资源,并且该提案一路绿灯通过。(明白明白)。自述文件为谷歌的许多应用程序节省了高达15%的CPU和内存使用量,这主要是由于减少了垃圾收集CPU时间和堆内存使用量。经过在vmihailenco/golang-memory-arenas项目中的实际性能对比。竞技场:/usr/bin/timegorunarena_off.go77.27user1.28system0:07.84elapsed1001%CPU(0avgtext+0avgdata532156maxresident)k30064inputs+2728outputs(551major+292838minor)pagefaultsnaEXPERENT/GOwapsusedIarena:usr/bin/timegorunarena_on.go35.25user5.71system0:05.09elapsed803%CPU(0avgtext+0avgdata385424maxresident)k48inputs+3320outputs(417major+63931minor)pagefaults0swaps使用arena的代码运行得更快并且使用更少的内存。综上所述,Go的每一个人都在不断地尝试榨取Go在性能优化上的潜力。现在是时候手动管理内存了。从实际测试结果来看,是有效的。感兴趣的小伙伴可以从Go1.20开始试用。但需要注意的是,由于发现该特性存在严重的API问题(我想将arena应用到其他标准库中,但这是一件大事),社区需要认真思考后续的发展。目前处于停滞状态。从这个提议来看,果然是内部需求一路猛烈,直接冲向了主人。外需不温不火。真双标?推荐阅读醒醒吧,以后就没有Go2了!Go1.20的那些事:PGO、编译速度、错误处理等新特性,你知道多少?向斯威夫特学习?Go考虑简单的字符串插值特性