jvm垃圾收集器你学废了吗(三)

前言

第一篇文章说了Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(传送门)这六种收集器,第二篇文章说了经典的G1收集器(传送门),今天我们还要单独的说一下低延迟收集器Shenandoah,Shenandoah收集器是一款只有OpenJDk才会包含的,这时候问题来了 什么是OpenJDK和OracleJDk呢?
OpenJDK是JDK的开放源码版本,在JDK11之后两者几乎一致,这篇文章写得比较清楚OpenJDK和OracleJDK的区别
在这里插入图片描述

Shenandoah与G1收集器比较
  • Shenandoah和G1都采用相同的内存布局
  • 默认的回收策略也一样,都是优先回收价值最大的Region
  • Shenandoah摒弃了G1中耗费大量内存和计算资源去维护的记忆集
    Shenandoah采用的是“连接矩阵”,连接矩阵是一个来记录跨Region的引用关系。可以理解为一张二维表
  • 连接矩阵降低了处理跨代指针时的记忆集维护消耗
  • 在回收阶段G1收集器不能与用户线程并发,而Shenandoah则可以和用户线程并发

Shenandoah收集器的工作过程

Shenandoah的工作过程可分为9步,但是这9步有和G1相似的地方我就不多阐述了,可以看我上一篇博客详细说了G1收集器

  • 初始标记
    和G1一样,标记GC Roots ,同样也是 Stop The World
  • 并发标记
    和G1一样,标记处所有可达对象,这个阶段可与用户线程并发执行
  • 最终标记
    和G1一样,处理剩余的SATB(原始快照)
  • 并发清理
    这个阶段是处理那些整个区域没有一个存活对象的Region
  • 并发回收
    先把存活的对象移动到另一个Region区域中,但是这个过程是和用户线程并发的,就是出现用户线程访问旧对象地址的情况,Shenandoah用读屏障和“Brooks Pointers”的转发指针来解决,
    什么是读屏障:写屏障是对象的引用发生变化是会记录下来,读屏障就是读出这个地址
    什么是转发指针(Brooks是一个人名):当用户程序访问到旧对象的内存空间就会产生自陷中断,进入事先设定好的异常处理中,然后在转发的新的地址
  • 初始引用更新
    这个阶段没有把所有指向旧对象的引用修正为对象的新地址,而是仅仅确保并发回收阶段的收集线程都已经完成了任务,这个阶段需要非常短的停顿时间
  • 并发引用更新
    真正引用更新是这这个阶段,这个阶段是和用户线程并发执行的。
  • 最终引用更新
    这个阶段修正存在与GC Roots中的引用,也需要短暂的停顿时间
  • 并发清理
    回收这些标记的Region空间,供以后新对象分配使用

其实上面9个步骤中,最重要的就是并发标记、并发回收、并发引用更新 这三个阶段
在这里插入图片描述

总结

Shenandoah收集器作为第一款由非Oracle开发的垃圾收集器,表现出如此好的性能,基本上全部的工作过程都是并发的,初始标记和最终标记的停顿时间基本上是固定的,与堆的容量和堆中对象的数量没有正比例的关系!
看到这里, 你学废了吗?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章