• 作者:老汪软件技巧
  • 发表时间:2024-12-12 07:56
  • 浏览量:

大家好,我是煎鱼。

最近 Go 核心团队成员 @Michael Knyszek 发起针对 memory regions 的社区讨论。

image.png

试图引入新的基于区域的内存管理(Region-based memory management),并再次之前提到的 Arena 实验给捞一下。

“基于区域的内存管理” 是什么

在计算机科学中,基于区域的内存管理(Region-Based Memory Management)是一种内存管理方式,其中每个被分配的对象都会被归属到一个特定的区域(下也称:region)。

区域也被称为区段、场地、空间或内存上下文。一个区域是多个已分配对象的集合,这些对象可以通过一次性高效的操作被整体重新分配或释放。

在优势上,区域分配在内存的分配和释放上具有较低的开销!

业务背景

煎鱼注:为什么这次叫 “业务背景”。因为我感受到了他们 Google 想强烈把这个轮子放进 Go 里的冲动。所以就不是单纯的 “背景” 了。

之前有过 Arena 实验库。该类型允许直接将数据结构分配到其中,并允许批量提前释放 Arena 内存,首次提供了手动管理内存的方式。一度在圈内闹的很大。

但,作者很无语的表示:“很不幸的是,由于 Arean 与语言和标准库的兼容性较差,将 Arean 添加到标准库的提议被无限期搁置!”

image.png

这次再出现,想必就是 Google 团队里的 Go 同学还是想再试试。

新提案提案背景

在原有的 Arean 提案设计中,应用的 API 要使用 arean,必须接受一个额外的参数:要分配到哪个 arean。和 context 类似。

有太多的应用程序 API 需要更新才能很好地与 Go 语言的编写方式集成,而且这会让这些应用程序接口变得更糟糕。这也是最终被很多人反对的原因之一。

因此本次新提案提出了一种可组合的方法,即以用户定义的 goroutine-local 内存区域的形式来替代原先 arena 的方式。

具体设计

本次新提案提出的是新的库,造一个新轮子去覆盖老的轮子(:doge

region 库的函数签名如下:

package region
func Do(f func())
func Ignore(g func())

一共包含两个方法。看起来很少,但有一定的 “学问” 在。

以下具体讲讲两个方法的作用和使用方向。

1、Do 方法

函数作用:该方法创建一个新的 region,并在该 region 中调用参数 f(闭包函数)。当 Do 返回时,该 region 会被销毁。

核心特性如下:

2、Ignore 方法:

函数作用:该方法让 g 及其调用链忽略当前 goroutine 上已激活使用的 region。用于排除已知生命周期长于 region 的内存,从而更高效地利用 region。

内存管理采用什么策略_华为自动管理和手动管理区别_

性能上,使用 Ignore 主动排除内存比自动解绑更高效。作为兜底逻辑,在没有激活 region 的情况下调用 Ignore 方法不会有任何效果。

使用例子

官方给出的最简单的基本例子。

代码如下:

var keep *int
region.Do(func() {
 w := new(int)
 x := new(MyStruct)
 y := make([]int10)
 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 本次在讨论阶段,相信很快就会进入下个阶段。我们通过本文先进行快速了解。可以继续保持关注和期待!

文章持续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub /eddycjy/blo… 已收录,学习 Go 语言可以看 Go 学习地图和路线,欢迎 Star 催更。