深入理解Java虚拟机——Shenandoah收集器(一)

61 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Shenandoah收集器的目标是能在任何堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内,相比G1收集器可以并发进行对象清理后的整理动作。

相比G1的区别

shenandoah是基于G1开发的垃圾收集器,相比于G1有以下区别

支持了并发的整理算法

并发整理的问题在于无法控制用户线程对移动对象的修改,Brooks提出了在对象布局结构的最前面增加一个新的引用字段,正常情况下将引用指向对象自己,并发移动时旧对象的值指向新的对象。Brooks指针存在以下两个问题

  1. 需要CAS进行并发写入

    如果在收集器线程“复制对象副本”和“修改旧对象Brooks指针”之间用户线程更新了对象中的某个字段,那么这个修改就没有同步到新对象上,因此Shenandoah通过CAS来保障修改Brooks指针时旧对象没有被修改过。

  2. 注意指向频率

    为了覆盖全部对象的访问操作,Shenandoah不得不同时设置读、写屏障去拦截。

默认不使用分代收集

不会有专门的新生代Region和老年代Region的存在

简化记忆集

摒弃了G1中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩阵”的全局数据结构来记录Region的跨代引用关系,降低了处理跨代指针时的记忆集维护消耗,也降低了伪共享问题的发生概率。连接矩阵可以理解一张二维表格:Region N中有对象指向Region M,那么在第N行第M列打上一个标记。

image.png