Go 是一种垃圾回收语言:
Http://golang.org/doc/go_faq.html#garbage_collection
这里说它是一个标记和清除垃圾收集器,但是它没有深入研究细节,并且正在进行替换... 然而,自从 Go 发布以来,这一段似乎没有更新多少。
它仍然是标记和扫描? 它是保守的还是精确的? 它是代?
这是 GC 的实现:
Https://github.com/golang/go/blob/master/src/runtime/mgc.go
来源:
GC 与 mutator 线程并发运行,类型准确(也称为精确) ,允许多个 GC 线程并行运行。它是使用写障碍的并发标记和扫描。它是非分代和非压缩的。分配是使用按 P 分配区域分隔的大小来完成的,这样可以最小化碎片,同时在通常情况下消除锁。
Go 1.4 + 垃圾收集器计划:
Go 1.3垃圾收集器在 Go 1.1之上的更新:
Go 1.1垃圾收集器:
Go 1.0垃圾收集器:
Replacing the GC with a different one is controversial, for example:
我不确定,但是我认为目前的 GC (技巧)已经是一个并行的 GC,或者至少是一个 WIP。因此,停止世界财产不再适用或不会在不久的将来。也许其他人可以更详细地澄清这一点。
(适用于 去1.8-Q12017,见下文)
The next Go 1.5 同时 Garbage Collector involve being able to "pace" said gc. 下面是一个提交给 在这张纸上的建议,它可能适用于 Go 1.5,但也有助于理解 Go 中的 gc。
您可以看到状态 before1.5(Stop The World: STW)
在 Go 1.5之前,Go 使用了 parallel stop-the-world(STW)收集器。 虽然 STW 集合有很多缺点,但它至少具有可预测和可控的堆增长行为。
(图片来自 GopherCon 2015讲座“ Go GC: 解决 Go 1.5中的延迟问题”)
STW 收集器的唯一调优旋钮是“ GOGC”,即收集之间的相对堆增长。默认设置为100% ,在堆大小比活动堆大小增加一倍时触发垃圾回收,如上一次回收时所示:
STW 收集器中的 GC 计时。
Go 1.5引入 并发收集器并发收集器。 这比 STW 集合有许多优点,但它是 m使堆增长更难控制,因为应用程序可以在垃圾收集器运行时分配内存。
为了达到相同的堆增长限制,运行时必须更早地启动垃圾收集,但是提前多久取决于许多变量,其中许多变量无法预测。 过早启动收集器,应用程序将执行太多垃圾收集,从而浪费 CPU 资源。 启动收集器的时间太晚,应用程序将超过所需的最大堆增长。 要在不牺牲并发性的情况下实现正确的平衡,需要仔细调整垃圾收集器的速度。 GC 配速旨在沿着两个维度进行优化: 堆增长和垃圾收集器使用的 CPU。
为了达到相同的堆增长限制,运行时必须更早地启动垃圾收集,但是提前多久取决于许多变量,其中许多变量无法预测。
要在不牺牲并发性的情况下实现正确的平衡,需要仔细调整垃圾收集器的速度。
GC 配速旨在沿着两个维度进行优化: 堆增长和垃圾收集器使用的 CPU。
The design of GC pacing consists of four components: 一个 GC 周期所需扫描工作量的估计值, a mechanism for mutators to perform the estimated amount of scanning work by the time heap allocation reaches the heap goal, 当 mutator 协助未充分利用 CPU 预算时用于后台扫描的调度程序,以及 GC 触发器的比例控制器。 设计平衡了 两种不同的时间观: CPU 时间和堆时间。 CPU 时间 类似于标准的挂钟时间,但是通过 GOMAXPROCS的速度要快一倍。 也就是说,如果 GOMAXPROCS为8,那么每一墙秒将传递8个 CPU 秒,而 GC 每一墙秒将获得2秒的 CPU 时间。 CPU 调度程序管理 CPU 时间。 一堆时间的传递是以字节为单位的,随着 mutator 的分配而向前移动。 堆时间和墙时间之间的关系取决于分配率,并且可以不断变化。 Mutator 协助管理堆时间的流逝,确保在堆达到目标大小时,估计的扫描工作已经完成。 最后,触发器控制器创建一个反馈回路,将这两个时间视图绑定在一起,从而优化堆时间和 CPU 时间目标。
The design of GC pacing consists of four components:
设计平衡了 两种不同的时间观: CPU 时间和堆时间。
GOMAXPROCS
堆时间和墙时间之间的关系取决于分配率,并且可以不断变化。 Mutator 协助管理堆时间的流逝,确保在堆达到目标大小时,估计的扫描工作已经完成。 最后,触发器控制器创建一个反馈回路,将这两个时间视图绑定在一起,从而优化堆时间和 CPU 时间目标。
去1.8 GC 可能再次进化,与 「消除重新扫描污水处理堆叠」建议书
到 Go 1.7为止,剩下的一个无限制且可能非平凡的 停止世界(STW)时间来源是堆栈重新扫描。 我们建议通过切换到结合 汤浅式删除写屏障[汤浅90]和 Dijkstra 风格的插入写屏障[ Dijkstra’78]的混合写屏障来消除堆栈重新扫描的需要。 Preliminary experiments show that this can 将最坏情况下的 STW 时间缩短至50μs 以下, and this approach may make it practical to eliminate STW mark termination altogether.
到 Go 1.7为止,剩下的一个无限制且可能非平凡的 停止世界(STW)时间来源是堆栈重新扫描。
我们建议通过切换到结合 汤浅式删除写屏障[汤浅90]和 Dijkstra 风格的插入写屏障[ Dijkstra’78]的混合写屏障来消除堆栈重新扫描的需要。
Preliminary experiments show that this can 将最坏情况下的 STW 时间缩短至50μs 以下, and this approach may make it practical to eliminate STW mark termination altogether.
在 公告在这里中,您可以看到相关的源提交是 70bfe和更早的版本。