ZGC 垃圾收集器染色指针详解

初始状态,视图 Remapped

ZGC 垃圾收集器染色指针详解_第1张图片

,其中,大方块是 region,小方块是对象,小方块上面数字是对象地址,下面的是该对象引用的其他对象的地址,r-4代表 remmaped 视图下地址为4,其他同理,m0代表mark0视图,m1代表mark1视图。

第一步 初始标记,视图切换为 mark1,STW

ZGC 垃圾收集器染色指针详解_第2张图片

这一步只标记根集合的引用。 

第二步 并发标记&并发重映射

ZGC 垃圾收集器染色指针详解_第3张图片

这一步标记整个堆,并完成并发重映射。

其实并发重映射应该是理论上垃圾回收的最后一步,但是并发重映射需要扫描整个堆,耗费量比较大,考虑到标记阶段也会扫描整个堆,于是就和标记阶段合并了。

那么标记阶段是怎么体现并发重映射的呢?

我们对比初始状态和最终标记后的状态,我们发现初始状态里,对象引用既有 Remapped,也有 mark0;最终标记后,所有对象引用视图都变成了 mark1,并且将所有引用指针都更新为了最新的。

标记完成后,重映射也就完成了,所有的指针都变成了最新的。

第三步 最终标记,STW 

ZGC 垃圾收集器染色指针详解_第4张图片

STW,最终处理并发标记过程中,应用程序新的对象引用变更。

第四步 初始重分配,视图切换为 Remapped,STW 

ZGC 垃圾收集器染色指针详解_第5张图片

初始重分配后,根集合里的对象引用视图被更新为 Remapped,引用对象分配到新region的,也更新为重分配后的地址。

第五步 并发重分配

ZGC 垃圾收集器染色指针详解_第6张图片

其中,并发重分配期间,访问到旧对象,旧指针是可以自愈的。

例如,当访问对象1的属性对象4时,此时对象1里的引用是m1-4,首先会获取m1-4的视图为mark1,然后和当前视图Remapped比较,发现不相等,于是查询对象地址转移信息表,查到了4的新地址,于是将对对象4的引用由m1-4更新为r-4。

如果在对象地址转移信息表里没查到,表示对象没有被重分配,直接更新引用视图为Remapped,如对象3对对象7的引用。

第六步 再次回到第一步,只不过这次视图切换为 mark0

你可能感兴趣的:(java-基础知识,jvm,java,开发语言)