【问题标题】:Java: how to trace/monitor GC times for the CMS garbage collector?Java:如何跟踪/监控 CMS 垃圾收集器的 GC 时间?
【发布时间】:2017-08-25 14:48:48
【问题描述】:

我无法找到监控 JVM GC 内存耗尽问题的方法。

使用串行 GC,我们可以查看完整的 GC 暂停时间,并很好地了解 JVM 是否出现问题(例如,如果它花费了几秒钟以上)。

CMS 的行为似乎有所不同。

java.lang:type=GarbageCollector,name=ConcurrentMarkSweep MXBean(通过JMX)查询lastGcInfo 时,报告的持续时间是所有GC 步骤的总和,通常为几秒。这并不表示 GC 存在问题,相反,我发现太短的 GC 时间通常更多地表明存在问题(例如,如果 JVM 进入 CMS-concurrent-mark-start-> @987654324 @循环)。

我也尝试过jstat,它给出了垃圾收集所花费的累积时间(不确定它是用于旧 GC 还是新 GC)。这可以绘制成图表,但用于监控目的并非易事。例如,我可以解析jstat -gccause 输出并计算随时间的差异,并跟踪+监控(例如,在过去 X 分钟内进行 GC 所花费的时间)。

我将以下 JVM 参数用于 GC 日志记录:

-Xloggc:/xxx/gc.log
-XX:+PrintGCDetails
-verbose:gc
-XX:+PrintGCDateStamps
-XX:+PrintReferenceGC
-XX:+PrintPromotionFailure

如果没有其他可用的,解析 gc.log 也是一种选择,但最佳解决方案是使用 java-native 方式来获取相关信息。

信息必须是机器可读的(以发送到监控平台),因此不能使用可视化工具。我正在运行混合了 JDK 6/7/8 实例的生产环境,因此与版本无关的解决方案更好。

是否有一种简单的方法来监控 CMS 垃圾收集?我应该查看哪些指标?

【问题讨论】:

  • 您可以使用启用 GC 日志记录的 JVM 选项吗?
  • 是的,我已经在使用它们(问题已更新),但 gclog 解析是最后的解决方案,我想先用尽所有惯用方法。

标签: java memory-leaks garbage-collection jvm monitoring


【解决方案1】:

从根本上说,CMS 并发收集器需要两件事

  1. 并发周期的吞吐量跟上提升率,即每单位时间内存活到老一代的对象
  2. 老年代中有足够的空间用于并发周期中提升的对象

假设 IHOP 固定为 70%,那么当它在某个时间点达到 >90% 时,您可能会遇到问题。如果您进行一些不适合年轻代或寿命更长的大型分配(这完全是特定于应用程序的),甚至可能更早。 此外,您通常希望它在并发周期之外花费更多时间而不是在其中,尽管这取决于您调整收集器的紧密程度,原则上您可以让并发周期几乎一直运行,但是您的吞吐量余量非常小并在并发收集上消耗大量 CPU 时间。

如果您真的真的想避免偶发的 Full GC,那么由于碎片化(CMS 是非压缩的),您将需要更多的安全余量。我认为这无法通过 MX bean 进行监控,您必须启用一些特定于 CMS 的 GC 日志记录才能获取碎片信息。

【讨论】:

  • 你带来了非常好的见解,你能澄清一下你对IHOP的意思吗?我似乎更频繁地遇到并发模式故障,但我无法控制应用程序的对象分配大小。您认为减小 NewMem 大小会有所帮助,还是这些事件仅取决于对象大小?
  • IHOP = 一般的 InitiatingHeapOccupancyPercent 或专门用于 CMS 的 CMSInitiatingOccupancyFraction。至于您的其他问题,您需要提供更多数据(GC日志)
  • 实际上,您只询问了跟踪/监控。如果您需要有关收集器特定行为的帮助,这将是一个单独的问题
  • 同意,这个问题有点离题了。
【解决方案2】:

查看 GC 日志: 如果您已经启用了 GC 日志记录,我建议您使用 GCViewer - 这是一个开源工具,可用于查看 GC 日志并查看吞吐量、暂停时间等参数。

对于分析: 我没有看到问题中提到的 JDK 版本。对于 JDK 6,我建议使用 visualvm 来分析应用程序。对于 JDK 7/8,我建议使用任务控制。您可以在 JDK\lib 文件夹中找到这些。这些工具可用于查看应用在一段时间内和 GC 期间的执行情况(可以通过 visualvm UI 触发 GC)。

【讨论】:

  • JMC 可能不合适,因为它使用的商业功能需要在生产环境中获得许可,甚至可能在 openjdk 构建中不可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2014-08-18
  • 2011-07-16
  • 2014-08-26
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多