Java CMS垃圾收集器日志输出

时间:2012-01-17 11:32:50

标签: java garbage-collection

我正在使用Java CMS垃圾收集器并尝试了解日志行,如:

22609.787: [GC 22609.788: [ParNew: 1116101K->79200K(1310720K), 0.2369136 secs]     1551730K->516431K(6029312K), 0.2379422 secs] [Times: user=1.68 sys=0.02, real=0.24 secs] 
22610.741: [Full GC 22610.741: [CMS: 437230K->278442K(4718592K), 14.8596841 secs]   573355K->278442K(6029312K), [CMS Perm : 241468K->236967K(241856K)], 14.8694544 secs]   [Times: user=14.80 sys=0.13, real=14.87 secs] 
22635.415: [GC 22635.416: [ParNew: 1048576K->43613K(1310720K), 0.0904065 secs] 1327018K->322055K(6029312K), 0.0914701 secs] [Times: user=0.45 sys=0.00, real=0.09 secs] 

基于阅读http://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs CMS将在各种情况下进行完整的垃圾收集(例如,如果“清除尝试中的促销失败”),但根据该博客,它将记录完整GC的原因。

相反,我看到了adhoc完整的GC。它肯定是CMS,因为还有其他CMS日志条目。

是否有理由它可以完成GC而不记录原因?

编辑: 对不起,多个java安装(我继承了这个设置)。它实际上是使用jdk1.6.0_27

EDIT 不幸的是,JVM参数包含在配置文件中(这是一个在Tomcat上运行的商业应用程序),但我很确定它们是:

min.heapsize=6144m
max.heapsize=6144m
-Xss=512k
-XX:MaxPermSize=512m
-XX:NewSize=1536m 
-XX:MaxNewSize=1536m 
-XX:SurvivorRatio=4 
-XX:+UseConcMarkSweepGC 
-XX:+UseParNewGC 
-XX:+UseTLAB 
-XX:+UseCompressedOops 
-XX:+PrintVMOptions 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCTaskTimeStamps
-XX:+PrintCommandLineFlags 
-XX:+PrintGCApplicationStoppedTime 
-XX:StackShadowPages=20 
-XX:+DisableExplicitGC 

1 个答案:

答案 0 :(得分:2)

当ConcurrentMarkSweepGC确定要填充或已达到其低水位标记时,它将执行GC。 (我不相信这里的情况)

更有可能的是,某些代码直接调用System.gc()。例如。默认情况下,RMI每小时都会调用它。您可以尝试使用-XX:+DisableExplicitGC来查看它是否有所作为。如果确实如此,我会追查原因并阻止它发生(有些人只是保留此选项)。

另一个可能的原因是免费直接内存不足。直接内存仅在GC上清理,但对堆大小没有多大贡献,因此看起来您需要GC。当你用完直接内存时,它必须调用System.gc()来释放那些正在使用它的ByteBuffers。我解决它的方法是明确清理直接和内存映射的ByteBuffers,所以我不会用完。

此外,我会尝试Java 6更新30甚至Java 7更新2,因为它可能有更多可预测的行为(即使你不能使用它,它可以提供信息)

您可以尝试哪些可以告诉您GC被触发的内容(但并非总是如此)

`jstat -gccause {pid} 10s`