大家好,我是煎鱼。最近 Go1.20 中的手动管理内存受到了很多人的关注。众所周知,Go 是一门带垃圾回收(GC)的编程语言,可以进行自动的内存申请、释放等内存操作。带 GC 能简化编程时的心智成本,
顺晟科技
2023-02-26 10:13:24
15
大家好,我是炸鱼。
最近Go1.20中的内存手动管理引起了很多人的关注。众所周知,Go是一种带有垃圾收集(GC)的编程语言,可以自动申请和释放内存。
采取GC可以简化编程的心理成本,保证内存的安全性。当我们说“一般”时,也有例外。人们说是六个,但通常是七个。
Go出现异常。
新版Go1.20,基于Google自身需求,快速通过实践,正式支持arena,实现手动内存管理(目前为实验性)。
现在,您可以通过GOEXPERIMENT=arenas环境变量来启用它:
GoE experiment=arenasgorunmain . go这个特性允许程序员从一个连续的内存区域手动申请和分配一组内存对象,或者一次性释放。
重点是内存可以手动管理。
NewArena:创建新的竞技场内存空间。释放竞技场及其相关对象。新建:基于竞技场,创建一个新对象。MakeSlice:基于arena创建一个新切片。克隆:克隆一个竞技场对象并将其移动到内存堆中。
以下案例和性能测试都是基于Golang memory arenas [101指南]中uptrace分享的arena的例子,这里就不自己创建一个供参考了。
很适合我初学的时候当演示用,打算留着自己下次用的时候文档翻倍。
让我们赶快开始吧。代码如下:
导入“竞技场”
T型结构{
Foo字符串
bar[16]字节
}
func processRequest(req *http。请求){
//在函数的开头创建一个竞技场。
mem :=竞技场。纽瓦雷纳()
//在函数结束时释放arena
推迟记忆。免费()
//从应用竞技场申请一些对象。
对于I:=0;i 10我{
竞技场。New[T](mem 'T ')
}
//从申请的竞技场申请一个切片对象(指定长度和容量)。
切片:=竞技场。MakeSlice[T](mem,100,200 'T ')
}
如果想单独使用一个应用对象。克隆方法可用于单独处理。
以下代码:
//创建一个竞技场
mem :=竞技场。纽瓦雷纳()
Obj1 :=竞技场。New[T](mem 'T') //分配一个arena对象。
Obj2 :=竞技场。Clone(obj1) //复制arena上的一个对象,并将其移动到内存堆中。
Fmt。Println(obj2==obj1) //即使是基于抄袭,两者也不完全等同。
//发布竞技场,obj1不能用,obj2可以正常使用。
Mem。Free()释放第一个应用的arena,其中Clone方法会将obj1复制到新的内存堆中,并将其分配给obj2。以后可以继续单独使用obj2。
也可以与arena和reflect结合使用。以下代码:
var typ=反射。TypeOf((*T)(无))。元素()
mem :=竞技场。纽瓦雷纳()
推迟记忆。免费()
值:=反射。ArenaNew(记忆,典型)
Fmt.println (value.interface()。(* t)):
该方法的一般用法:
竞技场。makeslice [string] (mem,length,capacity' string ')如果需要申请新的切片并添加元素:
切片:=竞技场。MakeSlice[string](mem,0,0 'string ')
Slice=append(slice,'')需要注意的是,arena目前不支持地图。但是你可以通过泛型达到类似的效果。
竞技场原则上不支持字符串。但我们还是可以通过不安全的骚操作来变相实现。字符串方法。
以下代码:
Src :='我脑袋里的炸鱼'
mem :=竞技场。纽瓦雷纳()
推迟记忆。免费()
bs :=竞技场。MakeSlice[byte](mem,len(src 'byte '),len(src))
副本(bs,src)
STR:=不安全。string (BS [0],LEN (BS))应用的竞技场释放后,对应的字符串无法使用,需要特别注意。
这个允许手动内存管理的arena特性来自内部,提案也是一路绿灯通过。(明白)。
Readme为许多Google应用程序节省了高达15%的CPU和内存使用,这主要是由于垃圾收集CPU时间和堆内存使用的减少。
经过VMIHailenco/Golang-Memory-Arenas项目的实际性能对比。
没用的。竞技场:
/usr/bin/time go run arena_off.go
77.27用户1.28系统0:07.84已用1001% CPU(0 avg text 0 avg data 532156 max resident)k
30064输入2728输出(551主要292838次要)页面错误0交换使用arena:
go experiment=arenas/usr/bin/time go run arena _ on . go
35.25用户5.71系统0:05.09已用803% CPU(0 avg text 0 avg data 385424 max resident)k
48个输入3320个输出(417个主要63931个次要)页面错误0使用arena交换代码运行速度更快,使用的内存更少。
Go的人在不断的尝试挤压Go在性能优化上的潜力。现在是时候手动管理内存了。
实际测试结果表明该方法是有效的。
感兴趣的朋友可以从Go1.20开始试用,不过需要注意的是,该功能发现了严重的API问题(我想把arena应用到其他标准库,但这是一件大事),社区需要认真考虑后续的开发。目前处于停滞状态。
从这个提议来看,真的是一路内需猛,直接冲向大师。外需胆小。真的双标?
醒醒吧,以后没有Go2了!你对那些东西了解多少:PGO、编译速度、错误处理和其他新特性?学Swift?Go考虑了简单字符串的插值特性。