标记-压缩算法
GC 标记 - 压缩算法(Mark Compact GC)是将 GC 标记 - 清除算法与 GC 复制算
法相结合的产物。
一、Lisp2算法
标记阶段与标记-清除算法一样,压缩阶段就是让有用的对象覆盖掉没用的对象,这比复制算法好,不用牺牲半个堆空间。
完成该算法实现,至少要遍历3次堆:
- 找到有用的对象前面没用的对象
- 移动指针
- 移动对象。
优点:
可有效利用堆
缺点:
遍历三次堆不好,存在还进的空间。
二、Two-Finger算法
这是一种高效的算法,具体来说就是需要搜索 2 次堆。
Two-Finger 算法有着很大的制约条件,那就是“必须将所有对象整理成大小一致”。之前介绍的算法都没有这种限制,而 Two -Finger 算法就必须严格遵守这个制约条件。原因我们会在之后的内容中进行说明。
该算法的实现就是将List2算法的第一次遍历与第三次遍历合并,找到没用的对象后直接拿有用的对象替换它。这样一来不仅不需要存储没用的对象指针,也可以使遍历次数减少为两次:
- 移动对象
- 更新指针
优点:
相较于List2算法,即减少了时间,也减少了空间。
缺点:
- 制约条件,那就是“必须将所有对象整理成大小一致
- 无法保证有引用关系的对象在堆内相邻,所以无法使用缓存技术。
三、表格算法
这个算法和 Two-Finger 算法一样,都是执行 2 次压缩操作。
表格算法通过以下 2 个步骤来执行压缩:
- 移动对象(群)以及构筑间隙表格(break table)
- 更新指针
优点:
- 没有必要为压缩准备出多余的空间
- 保证有引用关系的对象在堆内相邻,可以使用缓存技术
缺点:
维护表格的代价比较大