简介

这是一个新增package,而且还是实验特性。默认情况下,无法使用该package,需要通过GOEXPERIMENT=arenas开启,GOEXPERIMENT=arenas go build .

相关issue: https://github.com/golang/go/issues/51317

虽然代码合并了,但为了表示官方不支持,且不推荐在生产环境使用,没有包含在最终的Go1.20的release note中,见详情

The arena text in the release notes makes them seem more official and supported than they really are, and we’ve already seen a couple blog posts based on that erroneous belief. Delete the text to try to set expectations better.

Go标准垃圾回收的作业流程,基本是垃圾回收器对所有对象进行跟踪标记(STW),如果没有使用,那么在下次分配内存的时候,就连带进行对象收回。

为了降低GC消耗,开发者能做的就是减少堆内存的分配(逃逸分析,多使用Direct Call,使用unsafe,使用sync.Pool对象池等手段),降低重复分配和释放的开销。

Arena的内存管理思路就是整体分配,一次清理。 Go Arena Memory Management

使用场景

这个在某些场景下是垃圾对象的产生是阶段性密集产生的,比如:

  • 批处理任务中,一个批处理任务完成后,可以一次性回收该任务的相关资源。
  • 游戏进入到下一个场景(或者level),可以把上一个场景(或者level)的相关资源批量释放。

简单的benchmark

uptrace的关于arena的博客中使用binary tree代码做benchmark。

meirongdev:arena/ (main✗) $ time GOEXPERIMENT=arenas go run main.go                                                                                              [13:51:53]
   stretch tree of depth 22       arenas: 1      nodes: 8388607    MB: 128.0
  2097152 trees of depth 4        arenas: 992    nodes: 65011712   MB: 992.0
   524288 trees of depth 6        arenas: 1015   nodes: 66584576   MB: 1016.0
   131072 trees of depth 8        arenas: 1017   nodes: 66977792   MB: 1022.0
    32768 trees of depth 10       arenas: 993    nodes: 67076096   MB: 1023.5
     8192 trees of depth 12       arenas: 911    nodes: 67100672   MB: 1023.9
     2048 trees of depth 14       arenas: 683    nodes: 67106816   MB: 1024.0
      512 trees of depth 16       arenas: 512    nodes: 67108352   MB: 1024.0
      128 trees of depth 18       arenas: 128    nodes: 67108736   MB: 1024.0
       32 trees of depth 20       arenas: 32     nodes: 67108832   MB: 1024.0
long lived tree of depth 21       arenas: 1      nodes: 4194303    MB: 64.0
GOEXPERIMENT=arenas go run main.go  26.53s user 9.06s system 707% cpu 5.028 total
daomin:arena/ (main✗) $ cd ../binary_tree                                                                                                                    [23:56:55]
daomin:binary_tree/ (main✗) $ time go run main.go                                                                                                            [23:57:08]
stretch tree of depth 22         check: 8388607
2097152  trees of depth 4        check: 65011712
524288   trees of depth 6        check: 66584576
131072   trees of depth 8        check: 66977792
32768    trees of depth 10       check: 67076096
8192     trees of depth 12       check: 67100672
2048     trees of depth 14       check: 67106816
512      trees of depth 16       check: 67108352
128      trees of depth 18       check: 67108736
32       trees of depth 20       check: 67108832
long lived tree of depth 21      check: 4194303
go run main.go  62.85s user 1.01s system 1006% cpu 6.344 total
指标 arena no arena
用户CPU时间 26.53s 62.85s
系统CPU时间 9.06s 1.01s
总CPU使用率 707% (约7核) 1006% (约10核)
总执行时间 5.028秒 6.344秒

binary tree with arena代码 binary tree without arena代码

更多细节的参考资料