大家好,我是煎鱼。,最近 Go1.20 中的手动管理内存受到了很多人的关注。众所周知,Go 是一门带垃圾回收(GC)的编程语言,可以进行自动的内存申请、释放等内存操作。,带 GC 能简化编程时的心智成本,也保证了内存的安全。我们说 “一般”,也就是有例外。人们说六个,一般都有七个。,Go 的例外就出现了。,新版本 Go1.20,基于 Google 自身的需求,快速通过了实践,正式支持了 arena,能够实现手动的内存管理(当前是实验性特性)。,现在可以通过 GOEXPERIMENT=arenas 环境变量启用:,该特性可以让程序员手动的从一个连续的内存区域申请、分配一组内存对象,也可以一次性的释放。,重点是可以手动管理内存。,以下案例和性能测试是基于 uptrace 在 Golang memory arenas [101 guide][1] 中分享的 arena 例子,本处进行引用,我就不自创一份了。,很适合在初学时作为 Demo 使用,打算也留着自己下次用时结合文档翻一番。,一起来快速入门。代码如下:,如果要单独使用某个申请出来的对象。可以借助 Clone 方法进行单独处理。,如下代码:,释放了最早申请的 arena,Clone 方法在这里将会把 obj1 拷贝到新的内存堆上,再赋值给 obj2。后续要单独用 obj2 就可以继续使用。,也可以结合 arena 和 reflect 两个标准库来进行使用。如下代码:,该方法的常规用法:,如果需要申请一个新切片并追加元素:,需要注意的是,arena 目前不支持 map。但你可以通过泛型来实现类似的效果。,原则上 arena 不支持 string。但是我们依然可以通过 unsafe.String 方法的骚操作来变相实现。,如下代码:,在申请的 arena 释放后,该对应的 string 就无法使用了,需要特别注意。,这个允许手工管理内存的 arena 的特性是来源于内部,提案也是一路绿灯通过。(懂得懂)。,自述已经为 Google 许多应用节省了高达 15% 的 CPU 和内存使用量,主要原因是减少了垃圾收集 CPU 时间和堆内存使用量。,经过在 vmihailenco/golang-memory-arenas[2] 项目中实际的性能对比。,没有用 arena:,使用了 arena:,使用了 arena 的代码运行速度更快,且使用的内存更少。,Go 的各位大大们在性能优化中,不断地试图压榨 Go 的潜力。现在已经到了手工管理内存的阶段了。,实际的测试结果来看,是有作用的。,有兴趣的小伙伴可以在 Go1.20 起就开始试用。不过需要注意,该特性由于发现了严重的 API 问题(想把 arena 应用到其他的标准库中,但这是个大事件),社区还需要认真思考后续的发展,现阶段处于处于停滞状态。,从这次提案来看,真的是,内部需求一路猛如虎,直接冲上 master。外部需求就畏畏缩缩了。真双标?
© 版权声明
文章版权归作者所有,未经允许请勿转载。