Java 通过分代功能增强 Z 垃圾收集器

JEP 439:Generational ZGC 在 JDK 21 中从 Targeted 提升为 Completed

JEP 439 提出了通过扩展 Z 垃圾收集器(ZGC)来维护年轻对象和年老对象的独立分代,从而提升应用程序性能。这一改进允许 ZGC 更频繁地收集年轻对象,因为这些对象往往生命周期较短。

ZGC 的背景与特性

Z 垃圾收集器自 JDK 15 起已可用于生产环境,设计目标是低延迟和高可扩展性。ZGC 在执行大部分工作时,应用程序线程仍在运行,仅短暂暂停线程。其暂停时间通常以微秒计,因此特别适合需要低延迟和高可扩展性的工作负载。

Generational ZGC 的目标与优势

Generational ZGC 旨在降低分配停滞的风险,减少所需的堆内存开销,并降低垃圾回收的 CPU 开销。这些改进预计不会显著降低吞吐量。非分代 ZGC 的关键特性,如暂停时间不超过 1 毫秒、支持从几百兆字节到数太字节的堆大小,将得以保留。

Generational ZGC 基于弱分代假设,即年轻对象往往生命周期短,而年老对象则长期存在。通过更频繁地收集年轻对象,ZGC 可以提升应用程序性能。

使用 Generational ZGC

Generational ZGC 将与非分代 ZGC 共同存在。用户可以通过在命令行选项 -XX:+UseZGC 中添加 -XX:+ZGenerational 来选择 Generational ZGC。未来版本中,Generational ZGC 将成为默认选项,最终非分代 ZGC 将被移除。

$ java -XX:+UseZGC -XX:+ZGenerational ...

堆的分代设计

Generational ZGC 将堆分为两个逻辑代:年轻代用于存放新分配的对象,年老代用于存放长期存活的对象。每代独立收集,使得 ZGC 能够专注于收集有价值的年轻对象。

Generational ZGC 的设计特点

Generational ZGC 引入了多个设计概念,使其区别于非分代 ZGC 和其他垃圾收集器,包括:

  • 无多映射内存
  • 优化屏障
  • 双缓冲记忆集
  • 无需额外堆内存的重新定位
  • 密集堆区域
  • 大对象处理
  • 完全垃圾回收

性能改进

Generational ZGC 通过更频繁地收集年轻对象,提供了更低的延迟、更少的内存开销和更高的 CPU 利用率,使其在大多数用例中优于非分代 ZGC。

技术细节

Generational ZGC 引入了更复杂的系统,包括在加载和存储屏障中使用显式代码,并同时运行两个垃圾收集器。新系统消除了多映射内存的使用,使用户更容易测量堆内存使用情况,并可能将最大堆大小提高到非分代 ZGC 的 16TB 限制以上。

加载和存储屏障通过快速路径和慢速路径、记忆集屏障、SATB 标记屏障、融合存储屏障检查和存储屏障缓冲区等技术进行优化。Generational ZGC 还引入了双缓冲记忆集,用于精确跟踪代间指针,并允许在不增加堆内存的情况下进行重新定位,从而实现高效的年轻代收集。

未来展望

Generational ZGC 的引入是提升 Java 平台应用程序性能的重要一步。尽管系统更复杂,但长期目标是完全取代非分代 ZGC,以降低维护成本。虽然大多数用例将受益于 Generational ZGC,但某些非分代工作负载可能会经历轻微的性能下降。然而,潜在的开销预计会被不频繁收集年老对象的好处所抵消。

未来的改进和优化将基于基准测试和用户反馈进行。Generational ZGC 的引入是提升 Java 平台应用程序性能的重要进展。

阅读 28
0 条评论