Go 基于区域的内存管理,再战手动管理!
Go 基于区域的内存管理,再战手动管理!
Go语言核心团队成员Michael Knyszek发起了一项关于memory regions的社区讨论,试图引入新的基于区域的内存管理(Region-based memory management),并再次尝试之前提到的Arena实验。
“基于区域的内存管理” 是什么
在计算机科学中,基于区域的内存管理(Region-Based Memory Management)是一种内存管理方式,其中每个被分配的对象都会被归属到一个特定的区域(下也称:region)。区域也被称为区段、场地、空间或内存上下文。一个区域是多个已分配对象的集合,这些对象可以通过一次性高效的操作被整体重新分配或释放。在优势上,区域分配在内存的分配和释放上具有较低的开销!
业务背景
之前有过Arena实验库。该类型允许直接将数据结构分配到其中,并允许批量提前释放Arena内存,首次提供了手动管理内存的方式。一度在圈内闹的很大。但,作者很无语的表示:“很不幸的是,由于Arean与语言和标准库的兼容性较差,将Arean添加到标准库的提议被无限期搁置!”
这次再出现,想必就是Google团队里的Go同学还是想再试试。
新提案
提案背景
在原有的Arean提案设计中,应用的API要使用arean,必须接受一个额外的参数:要分配到哪个arean。和context类似。有太多的应用程序API需要更新才能很好地与Go语言的编写方式集成,而且这会让这些应用程序接口变得更糟糕。这也是最终被很多人反对的原因之一。
因此本次新提案提出了一种可组合的方法,即以用户定义的goroutine-local内存区域的形式来替代原先arena的方式。
具体设计
本次新提案提出的是新的库,造一个新轮子去覆盖老的轮子(:doge
region库的函数签名如下:
package region
func Do(f func())
func Ignore(g func())
一共包含两个方法。看起来很少,但有一定的“学问”在。以下具体讲讲两个方法的作用和使用方向。
- Do 方法
函数作用:该方法创建一个新的region,并在该region中调用参数f(闭包函数)。当Do返回时,该region会被销毁。
核心特性如下:
- 隐式内存绑定:在f及其调用链中分配的内存可能会被隐式绑定到当前的region。
- 自动解绑:内存在特定场景会自动从region中解绑,例如:
- 该内存被其他region引用。
- 被其他goroutine或调用方(包括Do的调用者及其上层调用者)引用;或被其他未绑定到此region的内存引用。
- 资源回收:如果region被销毁时仍有内存绑定到它,这些内存将由runtime主动回收。
- 性能优化:
- 正确使用时,可通过内存复用降低资源成本,减轻垃圾回收(GC)的压力。
- 错误使用可能增加资源成本,因为从region中解绑内存也有代价。
- 局部性:
- region仅对创建它的goroutine有效,不能传播到新创建的goroutine。
- 异常处理:
- 当f的执行因为panic或调用runtime.Goexit终止时,region会像正常返回一样销毁。
- Ignore 方法
函数作用:该方法让g及其调用链忽略当前goroutine上已激活使用的region。用于排除已知生命周期长于region的内存,从而更高效地利用region。性能上,使用Ignore主动排除内存比自动解绑更高效。作为兜底逻辑,在没有激活region的情况下调用Ignore方法不会有任何效果。
使用例子
官方给出的最简单的基本例子。
代码如下:
var keep *int
region.Do(func() {
w := new(int)
x := new(MyStruct)
y := make([]int, 10)
z := make(map[string]string)
*w = use(x, y, z)
keep = w // w从region中解除绑定
}) // x、y 和 z 的内存会被紧急清理,而 w 则不会。
这个例子想表述的是:所有主要的内置函数都适用于region功能。而且从region中泄漏的指针会导致其指向的内存从region中解除绑定。
嵌套的使用例子。
代码如下:
region.Do(func() {
z := new(MyStruct)
var y *MyStruct
region.Do(func() {
x := new(MyStruct)
use(x, z) // z 可在该内部 region 内自由使用
y = x // x 不受任何 region 的约束
})
use(y)
})
这个例子主要演示region嵌套region的使用。
总结
这次Go核心团队想要引入支持手动做内存管理的决心感觉非常大。毕竟arean被ban了后又沉淀了一段时间,马上又推出了region的新提案。Region本次在讨论阶段,相信很快就会进入下个阶段。我们通过本文先进行快速了解。可以继续保持关注和期待!