Shenandoah作为第一款不由Oracle(包括一起的Sun)公司的虚拟机团队所领导开发的HotSpot垃圾收集器。是只存在于OpenJDK当中的,最初由RedHat公司创建的,在2014年的时候贡献给了OpenJDK。

与G1相比的优点

从代码的历史渊源上来看,Shenandoah收集器更像是G1的下一代继承者,两者相似的堆内存布局,在初始标记、并发标记等许多阶段的处理思路都高度一致。
但是Shenandoah相比G1还是至少有三个明显的不同之处。
1、支持并发的整理算法,G1的回收阶段是可以多线程并行的,但却不鞥呢与用户线程并发。
2、Shenandoah是默认不使用分代收集的,不会有专门的新生代Region或者老年代Region的存在。
3、Shenandoah摒弃了在G1中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩阵”(Connection Matrix)的全局数据结果来记录夸Region的引用关系降低了夸代维护的消耗。
Shenandoah收集器的跨代“连接矩阵”示意图

连接矩阵可以简单的理解为一张二维表格,如果Region N有对象指向Region M,就在表格的N行M列中打上一个标记,如上图所示,如果Region 5中的对象Object C引用了Region 3 的Object B,Object B又引用了Region 1 的Object A,那么连接矩阵就中就会在5行3列、3行1列中打上标记。在回收时通过这张表格就可以得出哪些Region 之间产生了跨代引用。

收集过程

Shenandoah收集器的工作过程大致可以划分为以下九个阶段:

  • 初始标记:与G1一样,首先标记与GC Roots直接关联的对象,这个阶段仍是“Stop The World”的,但停顿时间与堆大小无关,至于GC Roots的数量相关。
  • 并发标记:与G1一样,编辑对象图,标记出全部可达的对象,与用户线程一起并发,时间长短与堆中存活对象的数量以及对象图的结构复杂程度有关。
  • 最终标记:与G1一样,处理剩余的SATB扫描,并在这个阶段统计出回收价值最高的Region,将这些Region构成一组回收集。此阶段也会有一小段短暂的停顿。
  • 并发清理:这个阶段用于清理那些整个区域内连一个存活对象都没有找到的Region。
  • 并发回收:这个阶段是Shenandoah与之前HotSpot中其他收集器的核心差异。在这个阶段,Shenandoah要把回收集里面的存活对象先复制一份到其他未被使用的Region中。但是有个难点是在移动对象的同时,用户线程仍然可能不停的对被移动的对象进行读写访问,移动对象之后整个内存中所有指向该对象的引用都还是旧对象的地址,这是很难一瞬间全部改变过来的。对于这个难点,Shenandoah将会通过读屏障和被称为“Brooks Pointers”的转发指针来解决
    并发回收阶段运行时间的长短取决于回收集的大小。
  • 初始引用更新:并发回收阶段复制对象结束后,还需要把堆中所有指向旧对象的引用修正蛋糕复制后的新地址,这个操作称为引用更新。这个阶段就是对这个操作进行初始化的,初始引用更新时间很短,会产生一个非常短暂的停顿。
  • 并发引用更新:真正开始进行引用更新操作,这个阶段是与用户线程一起并发的,时间长短取决于内存中涉及的引用数量的多少。
  • 最终引用更新:解决了堆中的引用更新后,还要修正存在于GC Roots 中的引用。这个阶段是Shenandoah的最后一次停顿,时间长短与GC Roots的数量有关。
  • 并发清理:经过并发回收和引用更新之后,整个回收集中所有的Region已再无存活对象,最后再调用一次并发清理过程来回收这些Region 的内存空间,供以后新对象分配使用。

这九个阶段的工作过程可能拆的比较琐碎,只要抓住其中三个最重要的并发节点(并发标记、并发回收、并发引用更新)就好理解Shenandoah的运作过程了。


转发指针(Brooks Pointer)

Shenandoah收集器的并发回收的核心是,转发指针。
转发指针的核心内容就是,在原有对象布局结构的最前面统一增加一个新的引用字段,在正常不处于并发移动的情况下,该引用指向对象自己。
如下图:

转发指针加入后带来的收益自然是当对象拥有了一份新的副本时,只需要修改一处指针的值,即旧对象上转发指针的引用位置,使其指向新对象,便可将所有对该对象的访问转发到新的副本上。这样只要对象的内存仍然存在,未被清理掉,虚拟机内存中所有通过旧引用地址访问的代码仍然可用,都会被自动转发到新对象上继续工作。
如下图:

Brooks Pointers 转发指针在设计上决定了它是必然会出现多线程竞争问题的。Shenandoah收集器是通过比较交换(Compare And Swap,CAS)操作来保证并发时堆中的访问正确性的。

总结

1、Shenandoah收集器保证了收集垃圾的低延迟。
2、但是使用了过多的写屏障,所以导致Shenandoah收集器的弱项很明显,当数据量大的时候会产生高运行负担而使得吞吐量下降。

深入理解JVM(③)低延迟的Shenandoah收集器相关推荐

  1. JVM垃圾回收器之Shenandoah收集器

    Shenandoah,第一款不由Oracle(包括以前的Sun)公司的虚拟机团队所领导开发的HotSpot垃圾收集器,这个项目的目标 是实现一种能在任何堆内存大小下都可以把垃圾收集的停顿时间限制在十毫 ...

  2. jvm低延迟垃圾收集器(Shenandoah)

    出入:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) 衡量垃圾收集器的三项最重要的指标是:内存占用(Footprint).吞吐量(Throughput)和延迟(Latency),三者共同构 ...

  3. JVM 低延迟垃圾收集器 Shenandoah 和 ZGC

    本文部分摘自<深入理解 Java 虚拟机第三版> 概述 衡量垃圾收集器的三项指标分别是:内存占用.吞吐量和延迟.这三者共同构成一个"不可能三角",即一款优秀的收集器最多 ...

  4. JVM Shenandoah收集器

    JVM Shenandoah收集器 深入理解java虚拟机 Shenandoah是由RedHat公司独立发展的新型收集器项目,在2014年RedHat把Shenandoah贡献给了OpenJDK 与G ...

  5. Shenandoah收集器和ZGC收集器的简单介绍

    3.6 低延迟垃圾收集器 衡量垃圾收集器的三项最重要的指标是:内存占用(Footprint).吞吐量(Throughput)和延迟(Latency),三者共同构成了一个"不可能三角" ...

  6. 深入JVM虚拟机(四) Java GC收集器

    转载自  深入JVM虚拟机(四) Java GC收集器 1 GC收集器 1.1 Serial串行收集器 串行收集器主要有两个特点:第一,它仅仅使用单线程进行垃圾回收:第二,它独占式的垃圾回收. 在串行 ...

  7. 「JVM 内存管理」低延迟的 Shenandoah GC 与 ZGC

    同时在内存占用(Footprint),吞吐量(Throughput),延迟(Latency)三方面表现得最优,才能称得上完美的垃圾收集器,但这几乎是不可能的(不可能三角,三元悖论,通常最多可以兼顾两项 ...

  8. 深入理解JVM(5) : Java垃圾收集器

    如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商.不同版本的虚拟机所提供的垃圾收集器都可能会有很大差 ...

  9. jvm系列二之GC收集器

    目录 参考 概念理解 并发和并行 吞吐量 GC垃圾收集器 Serial New收集器 Parallel New(并行)收集器 Parallel Scavenge(并行)收集器 Serial Old(串 ...

最新文章

  1. #sora#celery worker guide abstract
  2. python执行外部命令或URL
  3. 地大计算机学院教授,张静(地大教授)
  4. 我们为何要使用多线程,它有什么优点?
  5. 基于分位数回归的静态CoVaR计算 案例与代码
  6. 【C++ Primer】第四章学习笔记 (复合类型)
  7. 通过anaconda安装jupyter lab
  8. [笔记].Nios II 软核性能基准
  9. MD5加密、Base64加密解密
  10. Django访问静态资源
  11. java如何删除文件夹_java代码中如何删除文件夹呢?
  12. 最详细的3DMax 2019安装教程(从解压开始)
  13. swagger注解的使用
  14. “跨综服”——跨境电商综合服务合规化走向台前
  15. Python报错ModuleNotFoundError: No module named ‘pyqtgraph‘
  16. 多麦克风做拾音的波束_乱侃外设 篇四十二:一浪更比一浪强!HyperX Quadcast S 声浪加强版麦克风浅评...
  17. 计算机和打印机无法连接不上,电脑和打印机连接不上怎么回事
  18. 针孔相机(小孔成像)的原理(opencv之手眼标定--1)
  19. R绘图基础指南 | 2.折线图
  20. metasploit-学习7--显示post的模块的所有post信息

热门文章

  1. Linux备份还原数据( dump、restore)
  2. Unity之光源分类
  3. 恭贺乔迁之喜,发几个视频!
  4. python接口自动化(十七) requests获取响应时间(elapsed)与超时(timeout)
  5. JavaScript-二维数组
  6. mysql purge 线程_2 mysql的purge线程知多少?
  7. 正文内容过长时,offsetHeight的获取和监听变化
  8. string数组常用几种遍历
  9. 关于自定义微信分享内容的总结
  10. 【前端】同步异步区别