Go 语言原本 Go 语言原本
English

第 13 章 垃圾回收器

什么时候最适合做垃圾回收?没有人在看的时候。用摄像头追踪眼球的运动, 受试者的目光一离开屏幕,就执行垃圾回收。
When is the best time to do a GC? When nobody is looking. Using camera to track eye movement when subject looks away do a GC.
-- Rick Hudson, "Go GC: Latency Problem Solved", 2015

Hudson 在 GopherCon 2015 的演讲中,紧接着「回收延迟是首要障碍」一页提出了这个问题。玩笑之后的两页给出了另外两种办法:一是弹出一个等待网络的图标,二是以吞吐量换取更低的回收延迟。Go 1.5 选择的正是最后一种:回收器与程序并发运行,占用一部分 CPU 时间,以换取更短的停顿(13.12.2)。此后十年,回收器的演进大体围绕同一个问题展开:在停顿、CPU 开销与内存占用之间,怎样取得更好的平衡。

本章讨论 Go 的回收器如何实现这一取舍。13.1 介绍可达性、标记清扫与三色抽象,以及 Go 在各类回收器中的定位;13.2 讨论并发标记所需的写屏障,以及 Go 采用的混合写屏障。13.3 至 13.7 依次讨论一轮回收的各个环节:调步器如何依据 GOGC 与软内存限制决定何时启动回收,标记工作者与标记辅助如何分担标记的工作,清扫如何回收死去的对象,标记终止阶段如何判断标记已经完成,以及回收器如何借助栈映射找到栈上的指针。13.8 与 13.9 讨论两种尝试过而未被采用的方案,即分代回收与请求制导回收;13.10 讨论终结器、清理函数与弱指针;13.11 讨论 Go 1.26 起默认启用的 Green Tea。13.12 按时间回顾回收器的演进,13.13 以追踪与引用计数的统一理论回看 Go 的回收器。对象如何分配见第 12 章。