跳到主要内容

JEP 189:Shenandoah:低暂停时间垃圾收集器(实验)

概括

添加名为 Shenandoah 的新垃圾收集 (GC) 算法,该算法通过与正在运行的 Java 线程同时执行疏散工作来减少 GC 暂停时间。 Shenandoah 的暂停时间与堆大小无关,这意味着无论您的堆是 200 MB 还是 200 GB,您都将具有相同的一致暂停时间。

非目标

这并不是唯一一个统治所有这些的GC。还有其他垃圾收集算法将吞吐量或内存占用优先于响应性。 Shenandoah 是一种适合重视响应能力和可预测短暂停的应用程序的算法。目标不是解决所有 JVM 暂停问题。由于 GC 以外的原因(例如到达安全点时间 (TTSP) 问题或监控通货膨胀)而导致的暂停时间不属于本 JEP 的范围。

成功指标

如果我们能够保持一致的短GC暂停时间,这个项目将会成功。

描述

现代机器比以前拥有更多的内存和处理器。服务级别协议 (SLA) 应用程序保证 10-500 毫秒的响应时间。为了满足该目标的下限,我们需要垃圾收集算法,该算法必须足够高效,以允许程序在可用内存中运行,但也经过优化,不会中断正在运行的程序超过几毫秒。 Shenandoah 是 OpenJDK 的开源低暂停时间收集器,旨在让我们更接近这些目标。

Shenandoah 用并发 CPU 周期和空间来换取暂停时间的改进。我们为每个 Java 对象添加了一个间接指针,这使得 GC 线程能够在 Java 线程运行时压缩堆。标记和压缩是同时执行的,因此我们只需要暂停 Java 线程足够长的时间来扫描线程堆栈即可查找并更新对象图的根。

Shenandoah 算法在这篇 PPPJ2016 论文中进行了深入描述。

Shenandoah 已实施,并将由 Red Hat 支持 aarch64 和 amd64。

Shenandoah 的持续开发是在 OpenJDK Shenandoah项目中完成的。有关当前开发流程、实施细节、可用性的更多详细信息,请访问Shenandoah wiki 页面

备择方案

Zing/Azul 有一个无暂停的收集器,但是这项工作尚未贡献给 OpenJDK。

ZGC 有一个基于彩色指针的低暂停收集器。我们期待比较这两种策略的性能。

G1 做了一些并行和并发的工作,但它不做并发疏散。

CMS 进行并发标记,但它在暂停时间执行年轻代复制,并且从不压缩老生代。这导致需要花费更多时间来管理老一代的可用空间以及碎片问题。

构建和调用

作为实验性功能,Shenandoah 将-XX:+UnlockExperimentalVMOptions在命令行中要求。 Shenandoah 构建系统会自动禁用在不支持的配置上的构建。下游构建者可以选择禁用--with-jvm-features=-shenandoahgc在其他受支持的平台上构建 Shenandoah。

要启用/使用 Shenandoah GC,需要以下 JVM 选项-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

请参阅Shenandoah wiki 页面,了解有关如何设置和调整 Shenandoah GC 的更多信息。

测试

红帽已经对我们的重要应用程序进行了广泛的测试。我们开发了许多 Shenandoah 特定的 jtreg 测试。 Shenandoah 从 Fedora 24 开始在 Fedora 中发布,并作为 Rhel 7.4 中的技术预览版。运行标准 OpenJDK 测试-XX:+UseShenandoahGC应该足够了。

风险和假设

GC 接口(JEP 304)被集成在 JDK 11 中,此后对 GC 接口进行了许多扩展和改进。这最大限度地降低了将 Shenanodah 添加到 OpenJDK 源代码库的风险。除此之外,任何无法合理解决的 Shenandoah 特定代码路径都将受到#ifdef INCLUDE_SHENANDOAHGC或类似机制的保护。 Shenandoah GC 最初将被标记为实验性功能,因此-XX:+UnlockExperimentalVMOptions还需要-XX:+UseShenandoahGC.