JDK 17垃圾回收GC性能飞跃提升 - kstefanj


JDK 17 已经发布了几个月,它不仅包含了新的语言功能。在性能提升相比老版本的JDK也确实显著。与之前的 LTS 版本 JDK 8 和 JDK 11 相比,这一点变得尤为明显。 性能的大部分改进来自JVM中的新功能和优化,在这篇文章中,重点将放在垃圾收集领域的改进上.
  
不同类型GC服务于不同的用例
决定使用哪个垃圾收集器并不总是显而易见的。重要的是要明白,要做出正确的选择,您首先需要弄清楚您的主要目标是什么。通常目标是优化吞吐量、延迟和/或占用空间。最佳解决方案当然是针对上述所有情况进行优化,并在每种情况下获得最佳性能。收集器在各个方面都力求尽可能优化,但它们旨在进行不同的权衡以支持不同的用例。
快速总结我们在不同领域进行改进的含义:

  • 吞吐量- 降低 GC 对可在设定时间内完成的事务总数的影响
  • 延迟– 降低 GC 对任何单个事务的影响
  • 占用空间——降低 GC 使用的额外资源

做不同的权衡并不意味着不能从各个方面改进收集器。在改进收集器时,很大一部分是确保尽可能有效地进行权衡。另一个全面改进的好方法是重新评估旧的设计决策并提出更好的解决方案。
 
JDK JDK11和JDK17的吞吐量比较
查看吞吐量指标,我们看到与旧版本相比,所有收集器都有显着改进。ZGC是这方面改进最大的一个。G1 和 Parallel 在此设置中仍然具有更好的原始吞吐量,但扩展了堆,ZGC 弥补了这一差距。
当谈到这个指标时,我们还应该记住,我们不仅仅是在测量 GC 性能。Java 平台的其他部分,例如 JIT 编译器,也有助于这些改进。

  
延迟
从延迟的角度来看,结果得到了更大的改善。在这里,我们可以看到为缩短 GC 暂停时间所做的工作所带来的所有好处。当谈到这个指标时,很多改进确实可以对 GC 中的改进做出贡献。
当考虑这个指标时,G1 显示了最好的进展。从延迟的角度来看,ZGC 也有了很大的改进。最令人印象深刻的部分未在此图表中看到,因为基准测试正在测量应用程序延迟。

 
GC暂停
ZGC 在保持短暂停顿方面做得非常好,我们开始看到影响延迟分数的其他因素。如果我们看看暂停时间是如何改进的,我们可以看到ZGC 中发生了一些非凡的工作。
当考虑这个指标时,G1 显示了最好的进展。从延迟的角度来看,ZGC 也有了很大的改进。最令人印象深刻的部分未在此图表中看到,因为基准测试正在测量应用程序延迟。ZGC 在保持短暂停顿方面做得非常好,我们开始看到影响延迟分数的其他因素。如果我们看看暂停时间是如何改进的,我们可以看到ZGC 中发生了一些非凡的工作。

JDK 17 中的 ZGC 远低于其亚毫秒级暂停时间的目标。G1 的目标是在延迟和吞吐量之间保持平衡,远低于其默认的 200 毫秒暂停时间目标。该图表还包括一个额外的栏,用于快速显示不同收集器如何处理可扩展性。ZGC 被设计为具有不随堆大小扩展的暂停时间,我们清楚地看到当堆扩大到 128 GB 时就是这种情况。从暂停时间的角度来看,G1 比 Parallel 更好地处理更大的堆,因为它具有保持暂停时间目标的逻辑。
   
内存占用
此图表比较了三个不同收集器的峰值本机内存开销。由于从这个角度来看 Parallel 和 ZGC 都非常稳定,因此在这里查看原始数字也更有意义。我们可以看到G1在这方面确实有所改进,其主要原因是所有功能和增强功能使记忆集管理更加高效。
即使其他收集器没有减少他们的开销,我们仍然应该记住,他们在其他方面有所改进,而不必使用额外的内存。

 
总结
与旧版本相比,JDK 17的整体性能要好得多,无论您使用哪种收集器。如果您仍在使用 JDK 8 并计划升级,那么现在可能是重新评估要使用的 GC的好时机。在 JDK 8 Parallel 是默认设置,但在 JDK 9 中更改为 G1。从那时起,G1 以比 Parallel 更高的速度改进,但仍然存在 Parallel 是最佳选择的用例。随着 ZGC(自 JDK 15 以来的生产就绪)的引入,还有第三种高性能替代方案可以加入等式。​​​​​​​