Java:如何跟踪/监控CMS垃圾收集器的GC时间?

时间:2017-03-31 10:50:25

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

我无法找到一种监视JVM GC以解决内存耗尽问题的方法。

使用串行GC,我们可以查看完整的GC暂停时间,并且如果JVM遇到问题(例如,如果花费的时间超过几秒),则可以有一个非常好的概念。

CMS似乎表现不同。

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

我也尝试了jstat,它给出了垃圾收集所累积的时间(不确定它是旧的还是新的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实例的生产环境,因此与版本无关的解决方案更好。

是否有简单的(r)方法来监控CMS垃圾回收?我应该关注哪些指标?

2 个答案:

答案 0 :(得分:1)

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

  1. 并发周期的吞吐量以跟上促销率,即每单位时间内存活到旧代的对象
  2. 老一代足够的空间用于在并发周期中推广的对象
  3. 所以,让我们说IHOP固定为70%,那么当某个时刻达到> 90%时,你可能正在接近一个问题。甚至可能更早,如果你做一些不适合年轻一代或比他年长的大型分配(这完全是针对特定应用的)。 另外,你通常希望它在并发周期之外花费更多的时间而不是它,尽管这取决于你调整收集器的紧密程度,原则上你可以让并发周期几乎一直在运行,但是你的吞吐量余量非常小并发集合上的大量CPU时间。

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

答案 1 :(得分:0)

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

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