前言

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 和 ZGC

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

  2. [深入理解JVM虚拟机]第3章-垃圾收集器、内存分配策略

    垃圾收集器 判断对象是否需存活 回收堆 判断对象是否存活: 方法一:引用计数法.对象被引用一次就+1,当为0时回收对象.缺点:无法解决循环引用问题. 方法二:可达性分析算法.记录当前对象是否有和GC ...

  3. 深入理解java虚拟机笔记Chapter3-垃圾收集器

    垃圾收集器 垃圾收集(Garbage Collection,GC),它的任务是解决以下 3 件问题: 哪些内存需要回收? 什么时候回收? 如何回收? 本节补充知识: ① s:Survivor区 新生代 ...

  4. JVM学习记录3--垃圾收集器

    贴个图 Serial收集器 最简单的收集器,单线程,收集器会暂停用户线程,称为"stop the world". ParNew收集器 Serial收集器的多线程版本,其它类似.默认 ...

  5. JVM垃圾回收之CMS收集器

    从前文JVM垃圾回收几种常见算法和常见收集器我们知道,CMS是老年代垃圾收集器.CMS 收集器主要关注系统停顿时间.CMS 是 Concurrent Mark Sweep 的缩写,意为并发标记清除,从 ...

  6. 深入理解JVM(5)——HotSpot垃圾收集器详解

    HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器.根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率. ...

  7. 深入理解JVM(③)虚拟机的类加载器(双亲委派模型)

    前言 先解释一下什么是类加载器,通过一个类的全限定名来获取描述该类的二进制字节流,在虚拟机中实现这个动作的代码被称为"类加载器(Class Loader)". 类与类加载器 类加载 ...

  8. JVM实用参数(七)CMS收集器

    HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...

  9. JVM笔记-垃圾收集算法与垃圾收集器

    1. 一些概念 1.1 垃圾&垃圾收集 垃圾:在 JVM 语境下,"垃圾"指的是死亡的对象所占据的堆空间. 垃圾收集:所谓"垃圾收集",就是将已分配出去 ...

随机推荐

  1. JavaSE案例-Bank

    项目介绍 完成基本的银行业务功能 存款 取款 转账 查询余额 修改密码 修改预留手机号 注销账号 退出 任务分解: 定义三个基本类: BankTest():银行业务主程序 Bank(): 银行类,包含 ...

  2. 【JavaScript数据结构系列】06-双向链表DoublyLinkedList

    [JavaScript数据结构系列]06-双向链表DoublyLinkedList 码路工人 CoderMonkey 转载请注明作者与出处 1. 认识双向链表 不同于普通链表/单向链表,双向链表最突出 ...

  3. [ES6系列-06]展开操作符 Spread Operator 就像解压到这里

    [原创]码路工人 Coder-Power 大家好,这里是码路工人有力量,我是码路工人,你们是力量. github-pages 博客园cnblogs 在前面的文章中,介绍了...在获取剩余参数中的作用. ...

  4. NOIP 2017 P3959 宝藏 (状态压缩DP板子)

    洛谷题目传送门!! 题目的N这么小,当然是选择用状压DP啦!  等等,我好像不会状缩.... 首先,我们当然是要写状态转移方程了!! 那么,如果我们设  f[s]  状态s下,所要的最小花费,那么很显 ...

  5. TechEmpower Web 框架性能第19轮测试结果正式发布,ASP.NET Core在主流框架中拔得头筹

    TechEmpower 第19轮编程语言框架性能排行榜2020年5月28日正式发布,详见官方博客:https://www.techempower.com/blog/2020/05/28/framewo ...

  6. AES实现财务数据的加密解密存储

    需求背景 众所周知,金融行业有各种各样的财务报表,有些报表涉及到公司财务或经营相关的敏感数据,需要进行加密存储,只有掌握密钥的用户才能看到解密后的数据.注意,这里所说的加密并不是针对整个数据库或者表全 ...

  7. Codeforces Round #635 (Div. 2)部分(A~E)题解

    虽然打的是div1,但最后半小时完全处于挂机状态,不会做1C,只有个 \(O(n^3)\) 的想法,水了水论坛,甚至看了一下div2的AB,所以干脆顺便写个div2的题解吧,内容看上去还丰富一些(X) ...

  8. 学习源码的第八个月,我成了Spring的开源贡献者

    @ 目录 我的经历 碰到的问题 1.担心闹乌龙 2.不知道要怎么提交 3.英文 4.担心问题描述的不清楚 给你的建议 我的经历 关注我的朋友都知道,关注两个字划重点,要考! 我最近一直在写Spring ...

  9. 【Storm】编程模型

    元祖(tuple) 元组(Tuple),是消息传递的基本单元,是一个命名的值列表,元组中的字段可以是任何类型的对 象. Storm使用元组作为其数据模型,元组支持所有的基本类型.字符串和字节数组作为字 ...

  10. Linux、Android系统调用从上层到底层的调用路径浅析

    参考: https://blog.csdn.net/liuhangtiant/article/details/85149369 http://blog.sina.com.cn/s/blog_79433 ...