增量式垃圾回收
为了控制最大暂停时间,通过逐渐推进垃圾回收即垃圾回收与mutator交替执行。
三色标记算法
以标记-清除算法为例使用三色标记算法。
利用降低吞吐量来缩短最大停顿时间。
基础
- 将GC中对象分成三种颜色:
- 白色:还未搜索过
- 灰色:正在搜索
- 黑色:搜索完成
- 增量式的GC标记-清除算法分成以下三个阶段:
- 根查找阶段
- 标记阶段
- 清除阶段
执行过程
- 根查找阶段,直接将GC root直接引用的对象从白色涂为灰色,并将其加到标记栈。
- 标记阶段,每次标记一定数量对象,从标记栈中取出对象将其子对象涂成灰色,当标记阶段要结束时再次将GC root的直接引用的对象加入到标记栈,再次标记。
- 清除阶段,当标记栈为空时,每次清除一定数量的白色对象,对此执行次步骤直到遍历完整个堆。
写入屏障
- 由于标记阶段是多次完成的,因此可能产生“标记遗漏”即从黑色对象指向白色对象的指针。此时该白色的活跃对象会被认为是垃圾。
- 通过写入屏障解决,在修改指针时如果新引用的对象是白色的就将其标为灰色(加入到标记栈)
分配
- 分配时检查可用空间是否小于某个值,小于则开始进行GC(Mark-Sweep是内存不足才进行GC)。
- 分配时如果GC处于清除阶段,且分配位置还未遍历则需要给该对象标为黑色。
Steele的算法
- 标记阶段加入到标记栈时不设置标志,而是在遍历子对象时设置其标记标志。
- 写入屏障增加条件,标记过程中发生引用的对象是黑色对象且新的引用的目标对象为灰色或白色,则将发出引用的对象涂成灰色。
汤浅的算法
-原则:基于在GC开始时保留活动对象。
- 标记阶段不需要进行重新遍历GC root,因为其在写入屏障中如果GC处于标记阶段则将对该对象加入标记栈。
- 分配时如果处于标记阶段则将对象设为黑色。
RC Immix算法
合并型引用计数法
- 引用计数法由于频繁修改计数器导致吞吐量不高。设计一种把注意力放在某一时期最初和最后状态上,这期间不对计数器做修改,即合并型引用计数法。
- 引入更改缓冲区,指针的改动记录到该缓冲区。
- 当指针发送改变时将指针发送改变的对象和其所有子对象注册到更改缓冲区,通过写入屏障实现。
- 对象增加dirty标志,用于记录该对象是否写入了缓冲区。
- 当缓冲区满了时进行GC,先对对象当前的引用的子对象进行增量,而后对更改缓冲区记录的子对象进行减量,从而实现了对计数器的恢复。
- 优点在于增加了吞吐量
- 缺点则是增加了最大停顿时间
合并型引用计数法和Immix的融合
- 回收以线为对象,如果线内没有一个活动对象则回收该线。
- 线也增加计数器,表示线内存活对象数。
- 所有没经历过GC的新对象均会记录在更改缓冲区,在GC时只对新对象进行复制算法,实现被动的碎片整理。
- 积极的碎片整理,采用标记-压缩算法,选择一个块进行。