我无法找到一种监视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垃圾回收?我应该关注哪些指标?
答案 0 :(得分:1)
从根本上说,人们需要CMS并发收集器中的两件事
所以,让我们说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)。