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 平台应用程序性能的重要进展。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。