Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# 《垃圾回收算法手册读书》笔记之整理算法

发表于 2021-03-07 更新于 2022-06-11 分类于 Java ， gc ， jvm 阅读次数： 阅读次数： Disqus：

最近看了下这本垃圾回收算法手册，看到了第三章的标记-整理回收算法，做个简单的读书笔记

### 双指针整理算法

对于一块待整理区域，通过两个指针，free 在区域的起始端，scan 指针在区域的末端，free 指针从前往后知道找到空闲区域，scan 从后往前一直找到存活对象，当 free 指针未与 scan 指针交叉时，会给 scan 位置的对象特定位置标记上 free 的地址，即将要转移的地址，不过这里有个限制，这种整理算法一般会用于对象大小统一的情况，否则 free 指针扫描时还需要匹配scan 指针扫描到的存活对象的大小。

### Lisp 2 整理算法

需要三次完整遍历堆区域
第一遍是遍历后将计算出所有对象的最终地址（转发地址）
第二遍是使用转发地址更新赋值器线程根以及被标记对象中的引用，该操作将确保它们指向对象的新位置
第三次遍历是relocate最终将存活对象移动到其新的目标位置

### 引线整理算法

这个真的长见识了，
可以看到，原来是 A，B，C 对象引用了 N，这里会在第一次遍历的时候把这种引用反过来，让 N 的对象头部保存下 A 的地址，表示这类引用，然后在遍历到 B 的时候在链起来，到最后就会把所有引用了 N 对象的所有对象通过引线链起来，在第二次遍历的时候就把更新A，B，C 对象引用的 N 地址，并且移动 N 对象

### 单次遍历算法

这个一直提到过位图的实现方式，
可以看到在第一步会先通过位图标记，标记的方式是位图的每一位对应的堆内存的一个字（这里可能指的是 byte 吧），然后将一个存活对象的内存区域的第一个字跟最后一个字标记，这里如果在通过普通的方式就还需要一个地方在存转发地址，但是因为具体的位置可以通过位图算出来，也就不需要额外记录了