GC Roots 的时间比较短, 而且固定
但是 查找引用链 的 过程, 是和堆的大小成正比的, 可能会很久
所以必须让其大多数时间 不STW了, 用户线程一边进行, 一边遍历这个图
CMS
G1
这种并发的垃圾回收, 所谓并发, 也是就是"并发"这个阶段
所以都叫并发标记
三色标记法 来辅助推导
- 白:垃圾收集器还没访问过
- 灰:自己被访问过了, 但是至少还有一个它直接指向的节点是白的
- 黑: 被访问过了, 并且直接指向的节点没有白的
误杀的条件
会把活着的对象误以为没有连接的2个必要条件:
- 插入了 黑->白
- 删掉了 灰->->白 的联系,这里可能是间接的
这是因为, 要被重新被已经检查过的黑引用, 必须是本来有引用的(还没轮到扫描), 不然黑指不到, 必须是
本来被连着, 但是还没轮到检查的,切断原来的联系 (2)
被以为检查过的"黑"引用了(1), 才会误判
避免误杀的方案
有2个 都可以:
增量更新
CMS在用
新增 黑->白 时记下来
并发扫描
阶段结束后,
再以这些记录下来的黑为根, 扫描一次, 这在CMS里面叫3重新标记
,短STW
原始快照(SATB)
G1 Shenandoah 在用
删除的关系记下来,
并发扫描
阶段结束后,
以这些旧引用为根重新扫描一遍,这在G1里面叫3最终标记
,
这个比增量更新的重新标记
画的时间要短,
但是运行时记录关系,负担要大
网友评论