最新进展:Go arena 手动管理内存,鸽了!

大家好,我是煎鱼。

年初有给大家分享 Go1.20 arena 能手动管理内存的事情,当时不论是我们读者,还是社区上的小伙伴们,都是比较激动的。毕竟这是一个有意思的特性。

这不,今年都快过去了。2024 年要来了。有小伙伴问这个最新的进展:

今天这篇文章就是给大家同步目前的情况。第一节是前置知识,如果不太记得背景的同学可以快速看一下。

前置知识

Arena 指的是一种从一个连续的内存区域分配一组内存对象的方式 。优点比一般的内存分配更有效率,也可以一次性释放。当然了,它的重点是要手动管理内存。

Go 团队,基于 Google 自身的需求,快速通过了实践。在 Go1.20 支持使用环境变量启用:

go 复制代码
GOEXPERIMENT=arenas go run main.go

预计至少会提供以下 API:

  • NewArena:创建一个新的 arena 内存空间。
  • Free:释放 arena 及其关联对象。
  • New:基于 arena,创建新对象。NewSlice 等属于其派生方法,结果是一样的。
  • MakeSlice:基于 arena,创建新切片。
  • Clone:克隆一个 arena 的对象,并移动到内存堆上。

对应的示例代码如下:

go 复制代码
import (
 "arena"
 ...
)

type T struct {
 val int
}

func main() {
 a := arena.New()
 var ptrT *T
 a.New(&ptrT)
 ptrT.val = 1

 var sliceT []T
 a.NewSlice(&sliceT, 100)
 sliceT[99].val = 4

 a.Free()
}

手动调用 arena.New 方法分配 arena 内存,再调用 Free 方法进行释放。

简单来讲就是可以手动管理内存,就可以做很多事了,当然,也 "容易" 崩。

最新进展

其实这个 arena 提案当时已经快速的进入了实验阶段,大家以为能很快就能正式发布了。(毕竟来自 Google 内部的需求)

但这个特性引发了非常多的讨论,应该有超过 1k+ 条评论。

当前 arena 提案的状态为:自 2023 年 1 月 17 日起,由于严重的 API 问题,该提案被无限期搁置,GOEXPERIMENT=arena 代码可能会随时发生不兼容的更改或删除,我们不建议在生产中使用它。

由于过于繁杂,Go 核心团队成员@ Ian Lance Taylor,也表态:目前尚未做出任何决定,也不可能在短期内做出任何决定。

可以认为这个提案基本鸽了,因为已经快一年了,也没有新的破局思路。

争议点

原本如此高歌猛进的 arena 提案,是在哪卡壳阻塞了?从我猛翻 1k 楼层来看,以及官方给出的原因来看。

主要还是有一位同学提出:担心重走上下文(context)的老路!

目前 context 大量的渗透了 Go 所有库的 API,虽然很难评定好与不好。但是纯粹从语言设计的角度来看,上下文并不漂亮。

甚至我经常遇到同学来吐槽,咱们这个 ctx 放在函数第一个参数,或是放结构体里。到底是谁的设计。能不能像 Java 语言一样来个注解。

但 arena 不一样,一旦和 context 一样泛滥,将会带来更大的影响。你永远不知道你正在使用的第三方库,是否使用了手动管理内存 arena,是否会导致各种奇怪的问题。(除非你去翻代码和依赖)

因此 arena 库的出现,将会导致在创建对象时进行的一系列分配行为,将没有明确的界限,完全取决于应用他的库如何使用。同时在内部处理 arena 和非 arena 情况的实现代码,将使得 API 将变得更加污染。

最终大家还是希望 arena 能够在一定的界限范围内明确使用。但这一切均悬而未决。以上是我个人结合讨论所理解的提案阻塞缘由。

总结

Arena,这是一个非常受大家关注的特性,因为他可以在 Go 语言中做到手动管理内存,做更多的一些骚操作。以后就不用另辟蹊径走 CGO 了。

但潘多拉魔盒一旦打开,还是有潜在风险的。因此 arena 库很大概率会在找到更安全的 API 设计后,才会正式转为正式库对外公开。

当然,如果你想自己内部使用,且已经知悉风险。也可以直接在 Go1.20 使用 GOEXPERIMENT=arenas 也能够使用该实验特性。

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

Go 图书系列

推荐阅读

相关推荐
ZealSinger16 小时前
Go的DefaultClient超时为何总不生效
go·超时·context·net/http·defaultclient
我叫黑大帅18 小时前
Go日志库工程选型与逃逸分析评测报告
后端·面试·go
福兮说1 天前
Go 优雅退出:Shutdown 之后,后台 goroutine 还在跑(四个实测的坑)
后端·go
jeffwang1 天前
不装分词插件,用 PostgreSQL 做中文商品搜索:bigram + 向量 + RRF,以及「单字搜不到」这个坑
搜索引擎·postgresql·go
云浪1 天前
通过 Goroutine 搞懂 Go 并发与常见的 9 个坑
后端·go
福兮说2 天前
singleflight 防缓存击穿,这四个坑它不会替你挡
go
我的div丢了肿么办2 天前
自定义类型和类型别名以及实例化结构体的5种方式
后端·go
小满zs2 天前
Go语言第十三章(互斥锁,读写锁)
后端·go
福兮说2 天前
errgroup 的六个坑:Wait 之后 ctx 已取消、SetLimit 嵌套死锁,以及另外四个
后端·go
福兮说2 天前
Go 解析邮件的三个坑:GBK 标题、QP 正文,以及 NextPart 偷偷帮你做的事
后端·go