1

并发三色标记法

三色:黑、灰、白

  • 黑对象代表,对象自身存活,且其指向对象都已标记完成
  • 灰对象代表,对象自身存活,但其指向对象还未标记完成
  • 白对象代表,对象尙未被标记到,可能是垃圾对象

标记过程:

  1. 初始化:所有对象都被标记为白色
  2. 将根对象(全局对象、栈上局部变量等)置黑,将其所指向的对象置灰
  3. 从灰对象出发,将其所指向的对象都置灰. 所有指向对象都置灰后,当前灰对象置黑
  4. 标记结束后,白色对象就是不可达的垃圾对象,需要进行清扫

可能产生的问题

  1. 漏标 ->屏障机制

在某个对象标记为黑色之后,它新指向了一个对象,可能该对象之前被某灰色对象标记,还未扫描到,灰色对象就删除了对该对象的指向

  1. 多标 ->下一轮GC

在标记完一个灰色对象时,删除了指向它的黑色对象对它的引用

屏障机制

强弱三色不变式

  • 强三色不变式:白色对象不能被黑色对象直接引用
  • 弱三色不变式:白色对象可以被黑色对象引用,但要从某个灰对象出发仍然可达该白对象

插入写屏障

屏障机制类似于一个回调保护机制,指的是在完成某个特定动作前,会先完成屏障成设置的内容,插入写屏障(Dijkstra)的目标是实现强三色不变式,当一个对象引用另一个对象时,将被引用的对象标记为灰色。

删除写屏障

删除写屏障(Yuasa barrier)的目标是实现弱三色不变式,保证当一个白色对象即将被上游删除引用前,会触发屏障将其置灰,之后再删除上游指向其的引用。

混合写屏障

通过结合这两种写屏障技术,Go 的垃圾回收器可以在并发标记阶段运行,而无需停止整个程序(Stop-the-World)。

插入写屏障和删除写屏障的短板:

  • 插入写屏障:结束时需要STW来重新扫描栈,标记栈上引用的白色对象的存活;
  • 删除写屏障:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象。

混合写屏障操作:

  • GC 开始前,以栈为单位分批扫描,将栈中所有对象置黑
  • GC 期间,栈上新创建对象直接置黑
  • 堆对象正常启用插入写屏障(添加的对象置为灰色)
  • 堆对象正常启用删除写屏障(被删除引用的对象被标记为灰色)

桃瑾
1 声望1 粉丝

常常播种,有时收获