GC 三色标记法
Laiyong Wang Lv5

一、三色标记法

三色标记法是 Go 垃圾回收的核心算法,通过颜色标记对象状态,实现增量式垃圾回收:

  1. 颜色定义
    白色:未扫描或已确定为垃圾的对象。
    灰色:已发现但未完成扫描的对象(中间状态)。
    黑色:已扫描且确认存活的对象。
  2. 标记流程
    初始标记:所有对象为白色,根对象(全局变量、栈等)标记为灰色。
    并发标记:从灰色对象递归遍历引用链,标记为黑色。
    清除:回收所有白色对象。
  3. 目标:通过增量式标记减少 STW(Stop-The-World)时间,支持并发标记与程序运行。

二、写屏障(Write Barrier)

写屏障是并发标记阶段的关键技术,用于在对象引用关系变化时维护三色不变性,防止误回收:

  1. 插入写屏障
    规则:当黑色对象引用白色对象时,将白色对象标记为灰色。
    问题:需在标记结束后 STW 重新扫描栈,导致延迟。
  2. 删除写屏障
    规则:删除引用时,若被删对象为白色或灰色,则标记为灰色。
    问题:回收精度低,需下一轮 GC 处理残留对象。

三、混合写屏障(Hybrid Write Barrier)

Go 1.8 引入混合写屏障,结合插入与删除屏障优势,实现低延迟并发标记:

  1. 核心规则
    堆对象修改
    ◦ 新引用的对象(插入操作)标记为灰色。
    ◦ 旧引用的对象(删除操作)标记为灰色。
    栈对象处理
    ◦ GC 开始时将栈对象全部标记为黑色,后续新对象直接标记为黑色。
  2. 优势
    避免栈重复扫描:栈对象初始标记为黑色,无需 STW 重新扫描。
    弱三色不变性:允许黑色对象引用白色对象,但需灰色对象间接保护路径。
    低延迟:全程并发,STW 时间压缩至微秒级。
  3. 流程示例
    • 新增引用(堆):黑色对象 A → 白色对象 B → B 标记为灰色。
    • 删除引用(堆):黑色对象 C 删除引用 D → D 标记为灰色。

四、对比与总结

机制 特点 适用场景
插入写屏障 防止黑色引用白色,需 STW 重扫栈 早期 Go 版本(1.5 前)
删除写屏障 保护旧引用,精度低 小内存场景(嵌入式系统)
混合写屏障 结合两者,避免栈扫描,低延迟 Go 1.8+ 默认策略,高并发场景

五、工程启示

  1. 减少堆分配:使用对象池(sync.Pool)复用对象,降低 GC 压力。
  2. 避免指针滥用:值类型优先,减少引用链复杂度。
  3. 参数调优:通过 GOGC 调整触发阈值,平衡内存与性能。
  4. 监控指标:结合 pprof 分析堆内存、GC 耗时等关键指标。

通过三色标记法结合混合写屏障,Go 在保证低延迟的同时实现了高效的并发垃圾回收,成为高并发场景下的重要技术优势。