三色标记法基本原理
从程序根节点开始扫描,扫描到的标记为灰色。
广度优先的原则,从灰色标记表中,遍历所有灰色节点的下一级,将其标记为灰色。上一轮灰色表中的全部放入黑色表。
依次循环上一步。
最终白色节点说明没有被访问,需要回收。
这时候我们思考
但是扫描和回收的动作,可以与程序并行吗?
如果有并行面临的问题A:某个白色节点被黑色引用,同时被灰色断开,则永远不会被扫描到,从而错误地被回收。
因此,STW(stop the world,在做垃圾回收的时候,程序彻底停止等待)能保证不出现这个情况。但是 STW 会占用程序的时间。
那我们想办法如何避免上面出现的问题A。
首先我们分析下 A 这种情况出现的两个条件
1、白色被灰色引用,并抛弃
2、黑色引用白色
如何破坏这个两个条件呢?
黑色节点不允许引用白色节点
屏障机制
强-弱 三色不变式
强版:
直接破环条件2,黑色不允许引用白色,引用则报错弱版:
黑色可以引用白色,但是白色的上游必须有灰色(保证能被扫到),这个其实是破环的1和2不同时存在。
根据这个分析,GC 算法引入了屏障机制。
插入屏障
当黑色节点引用的白色节点,直接置为灰色。
1 | 添加下游对象(当前下游对象slot, 新下游对象ptr) { |