当前位置:Java -> Java CMS GC 调优

Java CMS GC 调优

Java Concurrent Mark and Sweep (CMS)算法通过将垃圾回收过程分为多个阶段,同时标记和清理内存区域,而无需显著暂停来运行。尽管其设计在减少暂停时间方面带来了好处,但也引入了独特的挑战,需要仔细调整和优化。在本文中,我们将探讨专门用于提高性能的CMS GC调整技术。但是,如果您想了解更多基础知识,可以观看JAX伦敦会议上的垃圾回收调优讲座

如何启用CMS GC

您可以通过在启动应用程序时添加以下JVM参数来在您的Java应用程序中启用并发标记 - 清除(CMS)垃圾收集器:

-XX:+UseConcMarkSweepGC


注意:从JDK 9开始,CMS GC算法已经被弃用,并且已经于JDK 14中完全移除,因为没有可靠的贡献者挺身而出来维护CMS。如果您的应用程序在JDK 9或更高版本上运行,则建议探索类似垃圾先进(G1)ShenandoahZGC等替代垃圾收集器以实现最佳内存管理。

何时使用CMS GC

如果您的应用程序具有以下任一要求,可以考虑使用CMS GC:

  1. JDK 14及更低版本: CMS自JDK 9起已被弃用,并且已完全从JDK 14中移除。注意力已经转向垃圾先进(G1)、Shenandoah和ZGC垃圾收集器。然而,对于在较早的JDK版本上运行的应用程序或特定用例的应用程序,可以考虑使用CMS。
  2. 低延迟要求: 当您的应用程序需要低且可预测的暂停时间时,例如在实时系统中,CMS可能是一个合适的选择。其并发性使其能够在不显著中断应用程序的情况下执行垃圾回收。
  3. 频繁的对象创建和删除环境: 在对象经常创建并频繁变得不可达的情况下,CMS可以有效地回收内存,而不会造成长时间中断,使其适用于具有动态内存模式的应用程序。
  4. 资源有限的JVM: 在系统资源(特别是内存)受限的环境中,CMS可能是一个实用的选择,因为它旨在平衡内存管理效率和最小中断。

CMS GC调优参数

在这一部分,让我们回顾一下您可以为您的应用程序配置的重要CMS GC调优参数。

1. -Xms-Xmx

-Xms在Java虚拟机(JVM)启动时设置初始堆大小,-Xmx设置JVM可以使用的最大堆大小。将这两个值设置为相同的值可以确保固定且不可调整的堆大小。这种配置可以减少与堆管理相关的卡顿,为您的应用程序提供稳定和可预测的内存使用。

2. -XX:CMSInitiatingOccupancyFraction

确定CMS收集器开始的堆占用百分比。该参数有助于根据内存使用情况对CMS初始化进行微调。例如,设置-XX:CMSInitiatingOccupancyFraction=75 意味着在占用率达到75%时CMS开始。 该初始化占用阀值的默认值约为92%,但该值可能会在不同版本之间发生变化。

3. -XX:+UseCMSInitiatingOccupancyOnly

CMS仅用于处理完整的垃圾收集。这在您想要更精确地控制CMS初始化的场景中很有用。设置后,CMS在达到占用分数和需要完整的垃圾收集时才会启动。

4. -XX:MaxGCPauseMillis

以毫秒为单位设置CMS的最大可接受暂停时间。该参数有助于控制垃圾收集期间的暂停时间。例如,设置-XX:MaxGCPauseMillis=500旨在将暂停限制为500毫秒。

5. -XX:+UseCMSCompactAtFullCollection-XX:+CMSParallelRemarkEnabled

启用CMS收集器的并行线程,提高了垃圾收集的整体效率。这些选项增强了CMS收集过程的不同阶段中的并行性。

6. -XX:ParallelCMSThreads-XX:MaxParallelCMSThreads

指定CMS收集器的初始和最大并行线程数量,影响收集过程中的并行性。

7. -XX:+UseLargePages

启用-XX:+UseLargePages选项可以优化Java堆性能。启用后,Java虚拟机(JVM)可以使用大页面,通常为2 MB或更大的页面,用于堆内存分配。以下是使用-XX:+UseLargePages的潜在好处:

  1. 减少TLB缺失: 大页面减少了转换查找缓冲区(TLB)缺失,简化了内存访问,提高了整体速度。
  2. 改善TLB效率更大的页面大小优化了TLB效率,导致更高效的内存转换。
  3. 提高速度: 较少的TLB缺失使应用程序体验到了改进的内存访问速度,这对于内存密集型操作特别有益。

注意:虽然启用大页面可以带来显著的性能优势,但必须注意,其有效性可能因应用程序和系统而异。此外,可能需要特定的操作系统级配置。

CMS GC高级选项

随着我们探索并发标记 - 清除(CMS)垃圾收集的复杂性,让我们深入探讨提供对其行为进行微妙控制的高级选项。这些选项超越了基础知识,为微调和优化CMS性能提供了额外的工具。

1. -XX:+UseCMSCompactAtFullCollection-XX:+CMSParallelRemarkEnabled

启用CMS收集器的并行线程,提高了垃圾收集的整体效率。这些选项增强了CMS收集过程的不同阶段中的并行性。

2. -XX:+UseCMSCompactAtFullCollection

启用此选项指导CMS在进行完整垃圾收集期间执行压缩阶段,可以帮助减少旧代中的片段,潜在地改善内存利用率。但是,请注意,压缩会引入额外的开销,应根据您的应用程序特性仔细评估其影响。

3. -XX:CMSFullGCsBeforeCompaction

此选项确定在启动压缩阶段之前应发生的完整垃圾收集次数。调整此参数可让您控制何时发生压缩,平衡减少碎片化带来的好处与相关成本。尝试不同的值以找到适合您的应用程序的最佳设置。

4. -XX:+CMSClassUnloadingEnabled

此选项允许CMS收集器在垃圾收集期间卸载类,可能释放更多内存。但是,请谨慎使用此选项,因为它可能对某些应用程序场景产生影响。

5. -XX:+CMSIncrementalMode-XX:+CMSIncrementalPacing

这些选项启用CMS收集器的增量模式,允许垃圾收集在较小的增量步骤中进行。这可以帮助减少暂停时间,但需要评估对整体吞吐量和响应性的影响。

6. -XX:CMSInitiatingPermOccupancyFraction

如果您的应用程序具有固定代(PermGen)空间(在Java 7及更早版本中很常见),则此参数确定CMS开始收集固定代的占用分数。

7. -XX:CMSClassUnloadingMaxInterval

指定CMS类卸载周期之间的最大间隔(以毫秒为单位)。如果类卸载对您的应用程序至关重要,则调整此参数可以影响类卸载发生的频率。

8. -XX:+CMSParallelInitialMarkEnabled

启用CMS收集器中初始标记阶段的并行线程。这可以增强初始标记过程的效率,减少暂停时间的影响。

9. -XX:CMSIncrementalSafetyFactor

指定CMS在增量模式期间增加其duty cycle长度的因子。调整此因子可以影响增量垃圾收集与应用程序吞吐量之间的平衡。

10. -XX:CMSMaxAbortablePrecleanTime

设置CMS在可中止的预清理阶段花费的最大时间(以毫秒为单位)。调整此参数可能对优化CMS性能至关重要,特别是在可中止的预清理时间比预期时间长的场景中。

11. -XX:CMSWaitDuration

定义CMS在等待请求的收集完成之前开始新收集之前等待的时间量。调整此参数可以影响CMS收集器在响应内存需求方面的积极性。

12. -XX:CMSParallelRemarkEnabled

在回标记阶段期间为CMS收集器启用并行线程。这可以增强回标记过程的效率,这是CMS收集周期中关键的一步。

13. -XX:CMSIncrementalDutyCycle

设置CMS在增量收集周期中应处于活动状态的时间百分比。调整此参数会影响增量收集与应用程序吞吐量之间的平衡。

14. -XX:CMSIncrementalOffset

指定CMS duty cycle时间中用于增量更新的百分比。此参数可以进行微调以优化CMS增量收集过程。

15. -XX:CMSRescanMultiple

控制在CMS周期期间重新扫描的卡片(堆的区域)数量。调整此参数可以影响CMS收集器的效率。

16. -XX:CMSWaitDuration

定义CMS在等待请求的收集完成之前开始新收集之前等待的时间量。调整此参数可以影响CMS收集器在响应内存需求方面的积极性。

研究CMS GC行为

通过分析GC日志来研究CMS GC的性能特征是最佳实践。GC日志包含有关垃圾收集事件、内存使用情况和其他相关指标的详细信息。有几种可用的工具可帮助分析GC日志,如GCeasyIBM GC & Memory visualizerHP Jmeter和 Google Garbage Cat。通过使用这些工具,您可以可视化内存分配模式,识别潜在瓶颈,并评估垃圾收集的效率。这有助于在优化性能时做出明智的决策。

总结

在本文中,我们探讨了从启用CMS到压缩和触发比率等高级选项的基本CMS JVM参数。此外,对大页面和类卸载的考虑为优化内存使用提供了启示。我们希望这将对您有所帮助。

推荐阅读: 8.你有两个罐子,50个红色弹球,50个蓝色弹球,如何将这100个球放入到两个罐子,随机选出一个罐子取出的球为红球的概率最大?

本文链接: Java CMS GC 调优