Excel不相邻列如何打印在一起-英雄云拓展知识分享
132
2023-11-07
【摘要】 本书摘自《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》一书中第3章,第6节,周志明著。
3.6.1 Shenandoah 收集器
在本书所出现的众多垃圾收集器里,Shenandoah 大概是最“孤独”的一个。现代社会 竞争激烈,连一个公司里不同团队之间都存在“部门墙”,那 Shenandoah 作为第一款不由 Oracle (包括以前的Sun) 公司的虚拟机团队所领导开发的HotSpot 垃圾收集器,不可避免 地会受到一些来自“官方”的排挤。在笔者撰写这部分内容时°,Oracle 仍明确拒绝在 OracleJDK12 中支持 Shenandoah 收集器,并执意在打包OracleJDK 时通过条件编译完全排 除掉了Shenandoah 的代码,换句话说, Shenandoah 是一款只有 OpenJDK 才会包含,而 OracleJDK 里反而不存在的收集器,“免费开源版”比“收费商业版”功能更多,这是相对
罕 见 的 状 况 ③ 。 如 果 读 者 的 项 目 要 求 用 到 Oracle 商 业 支 持 的 话 , 就 不 得 不 把 Shenandoah 排除在选择范围之外了。
最初 Shenandoah 是 由RedHat 公司独立发展的新型收集器项目,在2014年RedHat 把 Shenandoah 贡献给了 OpenJDK, 并推动它成为 OpenJDK 12的正式特性之一,也就是后来 的JEP189 。 这个项目的目标是实现一种能在任何堆内存大小下都可以把垃圾收集的停顿时 间限制在十毫秒以内的垃圾收集器,该目标意味着相比 CMS 和 G1,Shenandoah 不仅要进 行并发的垃圾标记,还要并发地进行对象清理后的整理动作。
从代码历史渊源上讲,比起稍后要介绍的有着 Oracle 正朔血统的ZGC,Shenandoah 反 而更像是G1 的下一代继承者,它们两者有着相似的堆内存布局,在初始标记、并发标记等 许多阶段的处理思路上都高度一致,甚至还直接共享了一部分实现代码,这使得部分对G1 的打磨改进和Bug 修改会同时反映在 Shenandoah 之上,而由于 Shenandoah 加入所带来的 一些新特性,也有部分会出现在G1 收集器中,譬如在并发失败后作为“逃生门”的Full GCθ,G1 就是由于合并了Shenandoah 的代码才获得多线程 Full GC 的支持。
那 Shenandoah 相比起G1 又有什么改进呢?虽然 Shenandoah 也是使用基于Region 的 堆内存布局,同样有着用于存放大对象的Humongous Region, 默认的回收策略也同样是 优先处理回收价值最大的 Region……但在管理堆内存方面,它与G1 至少有三个明显的不 同之处,最重要的当然是支持并发的整理算法,G1 的回收阶段是可以多线程并行的,但 却不能与用户线程并发,这点作为Shenandoah 最核心的功能稍后笔者会着重讲解。其 次 ,Shenandoah (目前)是默认不使用分代收集的,换言之,不会有专门的新生代Region 或者老年代Region 的存在,没有实现分代,并不是说分代对Shenandoah 没有价值,这 更多是出于性价比的权衡,基于工作量上的考虑而将其放到优先级较低的位置上。最后, Shenandoah 摒弃了在G1 中耗费大量内存和计算资源去维护的记忆集,改用名为“连接矩 阵”(Connection Matrix) 的全局数据结构来记录跨 Region 的引用关系,降低了处理跨代指 针时的记忆集维护消耗,也降低了伪共享问题(见3.4.4节)的发生概率。连接矩阵可以简 单理解为一张二维表格,如果Region N有对象指向 Region M, 就在表格的N 行 M 列中打 上一个标记,如图3-15所示,如果 Region5 中的对象 Baz引用了Region 3的 Foo,Foo 又 引用了Region1 的 Bar, 那连接矩阵中的5行3列、3行1列就应该被打上标记。在回收时 通过这张表格就可以得出哪些 Region 之间产生了跨代引用。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~