由于STW会影响程序的性能,因此将步骤3和步骤4的顺序调换,让步骤3的垃圾清除步骤与程序同时进行,能够减小STW的时长。
三色标记算法将程序中的对象分成白色、灰色,黑色三类:
将对象标记为白色节点
从根节点遍历得到灰色节点
遍历灰色节点,将灰色标记为黑色,遍历到的节点标记为灰色
重复操作
直到没有灰色节点
当程序和GC同时执行时,如果一个节点还没有被遍历,此时该节点为白色,程序运行时将原本的引用删除,让一个黑色节点引用该节点,则该节点不会被遍历,最后被删除。 对象2和对象4被标记为灰色
对象5被遍历之前被改变了引用
被对象1引用的对象5不会变成黑色,最后被删除
让程序运行过程满足强三色不变性或者弱三色不变性。
在程序的执行过程中添加一个屏障机制实现两种不变性 屏障机制分为插入屏障和删除屏障,插入屏障实现的是强三色不变式,删除屏障则实现了弱三色不变式。为了保证栈的运行效率,屏障只对堆上的内存对象启用,栈上的内存会在GC结束后启用STW重新扫描。
使程序满足强三色不变性,当白色节点被黑色节点引用时,将白色节点变为灰色,从而保留这个节点。缺陷:如果白色节点被栈上的黑色节点引用,不会触发插入屏障,最后还是会被删除。
使程序满足弱三色不变性,当白色节点的引用被删除时,将白色节点变为灰色,从而保留这个节点。缺陷:如果没有黑色节点引用这个白色节点,那么本来作为垃圾的白色节点将会被保留到下一轮GC。
解决插入写屏障和删除写屏障在结束时需要STW来重新扫描栈带来的性能问题
某时刻栈和堆的情况(栈一开始就都是黑的)
栈上新增对象4,堆上新增对象d
栈上删除对象1,堆上删除对象3
栈上删除栈上新增,堆上删除堆上新增
堆上删除栈上新增
栈上删除堆上新增