一句话定义

三色标记算法是一种 并发垃圾回收 策略,通过将对象分为三种颜色(黑、灰、白)来追踪对象的引用关系,从而实现一边运行程序一边回收内存。

核心工作流程

该算法将对象分为三色,本质是建立一个 “待处理队列”

  • 白色:潜在垃圾。标记结束仍为白色则回收。
  • 灰色:活跃对象,但其引用的子对象尚未扫描。
  • 黑色:活跃对象,且其引用的子对象已全部扫描。

标记步骤

  1. 初始状态:所有对象标记为 白色
  2. 根扫描 (Root Scan):在 STW 1 (Mark Setup) 阶段,从根对象(全局变量、栈变量)出发,将直接引用的对象标为 灰色
  3. 迭代扫描:从灰色集合取出一个对象标为 黑色,并将其引用的所有子对象标为 灰色,直到灰色集合为空。
  4. 清理回收:回收所有白色对象。

解决并发问题的关键:写屏障

为了防止并发修改导致活跃对象被误删,只要满足以下 任意一种 不变性,就能保证标记的正确性:

  • 强三色不变性:不允许黑色引用白色(源头切断)。
  • 弱三色不变性:黑色可引用白色,但该白色必须有灰色对象保护(路径可达)。

知识扩展

  • STW (Stop The World):三色标记虽然是并发的,但在开启和关闭写屏障时仍需短暂暂停程序。
  • 根对象 (Root Set):包括全局变量、Goroutine 栈上的指针、寄存器中的指针等。
  • 内存碎片:标记清除算法本身不移动对象,可能产生内存碎片,Go 通过分级分配(mspan)来缓解此问题。