GC目前的问题是,会暂停、阻碍代码的运行,即stop the world。增量式GC处理的就是这个问题。将GC变得可一阶段一阶段进行。
分阶段运行的思路并不难,但具体要解决的问题其实是分阶段GC后,如何保证下次继续时,中断过程中引用关系的变化不会对GC造成影响。
三色标记法是一个逻辑上的抽象,将对象分成白:未搜索,灰:正搜索,黑:已搜索。
在这里,和前面引用计数中提到的标色不一样,这里只是一个逻辑概念,在实现中并没有所谓的black, white。
mark_sweep按增量来排,可以分成三个阶段:根查找、标记、清除
incremental_gc() { case $gc_phase if GC_ROOT_SCAN root_scan_phase() if GC_MARK incremental_mark_phase() else incremental_sweep_phase () } root_scan_phase() { for r : $root mark(r) $gc_phase = GC_MARK } mark(obj) { if !obj.mark obj.mark = true push(obj, $mark_stack) // 理解下,不分段的GC中,由于是用递归方式直接深度搜索到底,所以不需要这个stack,而这个搜索过程目前会中断了,因此需要这样一个数据结构来记录。}
上面这mark,就逻辑上把根对象由白标记为灰了。
i