V1.3 标记清除
流程
- 暂停程序业务逻辑,找出不可达的对象和可达的对象(启动STW)
- 开始标记,程序找出他所有可达的对象,并坐上标记(Mark标记)
- 标记结束之后,然后开始清除未标记的对象(Sweep清除)
- 停止暂停,让程序继续跑,然后重复循环这个过程,直到process程序生命周期结束(停止STW)
缺点
- STW(stop the world): 让程序暂停,程序出现卡顿
- 标记需要扫描整个heap
- 清除数据会产生heap碎片
改进
以前的流程:启动STW Mark标记 Sweep清除 停止STW
现在的流程:启动STW Mark标记 停止STW Sweep清除
使STW尽量缩短,Sweep清除时程序不停止,与进程并行处理
V1.5 三色标记法
流程
- 只要是新创建的对象,默认的颜色都是标记为“白色”
- 每次GC回收开始,然后从根节点开始遍历所有对象,把遍历到的对象从白色集合放入“灰色”集合
- 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
- 重复第三步,直到灰色中无任何对象
- 回收所有的白色标记表中的对象,也就是垃圾回收
对象丢失现象条件(不被STW保护)
- 一个白色对象被黑色对象引用
- 灰色对象与他之间的可达关系的白色对象遭到破坏
强三色不变式
破坏条件一:一个白色对象被黑色对象引用
如果黑色的对象在运行时添加一个灰色的对象为引用这是可以的,如果想要添加一个白色的对象为引文是不被允许的(强制性的不允许黑色对象引用白色对象)
弱三色不变式
破坏条件二:灰色对象与他之间的可达关系的白色对象遭到破坏
黑色对象可以引用白色对象,但是白色对象存在其他灰色对象对他的引用,或者可达他的链路上游存在灰色对象(简单来说就是黑色可以引用白色,但是白色的上游不能没有灰色的对象,一旦丢失,在灰色对象中就漏了)
屏障机制
插入屏障(对象被引用时触发的机制)
注意:为了保证栈的速度,栈不执行插入屏幕机制,而是受STW暂停保护
具体操作:在A对象引用B对象的时候,B对象被标记为灰色(将B挂在A下游,B必须被标记为灰色)
满足:强三色不变式(不存在黑色对象引用白色对象的情况了,因为白色会强制变为灰色)
不足:GC结束时需要STW来重新扫描栈,大约需要10-100ms
删除屏障(对象被删除时触发的机制)
具体操作:被删除的对象,如果自身为灰色或者白色,那么被标记为灰色
满足:弱三色不变式(保护灰色对象到白色对象的路径不会断)
不足:回收精度低,一个对象即使被删除了最后一个指向他的指针也依旧可以活过这一轮,在下一轮GC中被清理掉
V1.8 三色标记法+混合写屏障机制
具体操作
- GC开始将栈上的对象全部扫描并标记为黑色(之后不在进行第二次重复扫描,无需STW)
- GC期间,任何在栈上创建的新对象,均为黑色
- 被删除的对象标记为灰色
- 被添加的对象标记为灰色
满足:变形的弱三色不变式(结合了插入 删除写屏障两者的优点)