原文链接:http://openjdk.java.net/jeps/333
作者 Per Liden, Stefan Karlsson
所有人 Per Liden
类型 特征
范围 实现
当前状态 结束/已交付
发布 11
组成 hotspot / gc
讨论 hotspot dash gc dash dev at openjdk.java.net
Effort L
持续 L
依赖项 JEP 312: 局部线程握手
JEP 304: 垃圾收集器接口
评估 Mikael Vidstedt, Stefan Karlsson
支持 Mikael Vidstedt
创建时间 2018/02/13 09:58
更新时间 2018/11/30 16:31
Issue 8197831

概要
Z 垃圾收集器,也被移为ZGC,是一种可伸缩的低延迟的垃圾收集器

目标:

  • GC暂停时间不应超过10ms
  • 可处理堆的范围从相对较小(几百MB)到非常大的(多TB)
  • 与使用G1相比之下,应用程序吞吐量减少不超过15%
  • 为将来的GC特性和利用彩色指针和负载屏障的优化打下基础
  • 最初支持的平台:Linux/X64

我们有很强烈的抱负,要在大量相关工作负载下实现这些目标。与此同时,我们也要承认,我们并不认为这些目标是每个可想象工作量的硬性要求
未实现的目标:
它的目标不是为Linux/x64以外的平台提供工作实现。
如果有足够的需求,可以稍后添加对其他平台的支持

动机:
垃圾收集是Java的主要优势之一.然而,当垃圾收集暂停时间过长它们将会对程序的响应时间产生影响.通过删除或大幅减少GC暂停的时长,我们将使Java成为更广泛的应用程序集的更有吸引力的平台
此外,现代系统中可用的内存数量还在继续增长。用户和应用程序开发人员希望JVM能够以一种有效的方式充分利用这种内存,并且不需要很长的GC暂停时间
描述:
一目了然,ZGC是一个并发的,单一代的,基于区域的NUMA感知的压缩收集器.STW阶段仅限于根描述.因此GC暂停时间不会随着堆或活动集的大小而增加.
ZGC的核心设计原则/选择是将负载障碍与彩色对象指针(即colored oops)结合使用。这使得ZGC能够在Java应用程序线程运行时执行并发操作,例如对象重定位。从Java线程的角度来看,在Java对象中加载引用字段的行为受到加载障碍的影响。除了对象地址之外,有色对象指针还包含加载屏障使用的信息,以确定在允许Java线程使用指针之前是否需要采取某些操作。例如,对象可能已被重新定位,在这种情况下,加载屏障将检测情况并采取适当的操作.
与替代技术相比,我们认为彩色指针方案提供了一些非常有吸引力的特性。特别是:

  • 它允许我们在重定位/压缩阶段回收和重用内存,然后修复指向回收/重用区域的指针。这有助于降低一般堆开销。这也意味着不需要实现单独的mark-compact算法来处理完整的GC。

  • 它允许我们拥有相对较少且简单的GC障碍。这有助于降低运行时开销。这也意味着在我们的解释器和JIT编译器中实现,优化和维护GC屏障代码更容易。

  • 我们目前在彩色指针中存储标记和重定位相关信息。但是,这种方案的通用性使我们能够存储任何类型的信息(只要我们可以将它放入指针中),并让负载屏障根据该信息采取它想要的任何动作。我们相信这将为未来的许多功能奠定基础。举一个例子,在异构内存环境中,这可以用于跟踪堆访问模式,以指导GC重定位决策,以便将很少使用的对象移动到冷存储。
    性能:
    使用SPECjbb®2015[1]进行了定期性能测量。从吞吐量和延迟的角度来看,性能看起来都很好。下面是使用128G堆的复合模式下比较ZGC和G1的典型基准分数(百分比,相对于ZGC的max-jOPS标准化)。

(越高越好)

ZGC
max-jOPS: 100%
critical-jOPS: 76.1%

G1
max-jOPS: 91.2%
critical-jOPS: 54.7%
以下是来自同一基准的典型GC暂停时间。ZGC设法远远低于10毫米的目标。请注意,确切的数字可能会有所不同(向上和向下,但不显着),具体取决于所使用的确切机器和设置。

(越低越好)

ZGC
avg: 1.091ms (+/-0.215ms)
95th percentile: 1.380ms
99th percentile: 1.512ms
99.9th percentile: 1.663ms
99.99th percentile: 1.681ms
max: 1.681ms

G1
avg: 156.806ms (+/-71.126ms)
95th percentile: 316.672ms
99th percentile: 428.095ms
99.9th percentile: 543.846ms
99.99th percentile: 543.846ms
max: 543.846ms
还对各种其他SPEC®基准测试和内部工作负载进行了特别性能测量。通常,ZGC设法保持一位数毫秒的暂停时间。

[1]SPECjbb®2015是标准性能评估公司(spec.org)的注册商标。实际结果未表示为合规,因为SUT可能不符合SPEC对一般可用性的要求。
限制:
ZGC的初始实验版本不支持类卸载。在ClassUnloading和ClassUnloadingWithConcurrentMark选项会默认被禁用。启用它们将不起作用。

此外,ZGC最初不会支持JVMCI(即Graal)。如果EnableJVMCI启用该选项,将打印错误消息。

这些限制将在本项目的后期阶段解决。
构建和调用:
按照惯例,构建系统默认禁用JVM中的实验-性-功-能。因此,作为实验-性-功-能的ZGC将不会出现在JDK构建中,除非在编译时使用configure选项明确启用--with-jvm-features=zgc。

(ZGC将出现在Oracle生成的所有Linux / x64 JDK版本中)

JVM中的实验功能也需要在运行时明确解锁。要启用/使用ZGC,因此需要以下JVM选项:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC。

有关如何设置和调整ZGC的更多信息,请参阅ZGC项目Wiki.
备选方案:

  • 一个明显的替代方案是向G1添加并发压缩功能。这种替代方案已被广泛制作原型,但最终被放弃了 我们发现将这种功能强制转换为从未为此目的设计的代码库是不可行的,同时保留了G1的稳定性和其他良好的属性。
  • 理论上的替代方案是以某种方式改进CMS。然而,有几个原因使得基于CMS算法的低延迟收集器既不具有吸引力也不可行。原因包括不支持压缩,未绑定的注释阶段,复杂的代码库以及已经弃用的事实(JEP 291)。
  • Shenandoah项目正在探索使用Brooks指针来实现并发操作(JEP 189)。
    测试:
    我们现有的大多数功能和压力测试都是收集器无关的,可以按原样重复使用。将添加针对特定于ZGC的属性和功能的附加测试
    依赖:
    JEP 304:垃圾收集器接口
    JEP 312:线程局部握手