Java CMS垃圾收集器日志输出

4
我正在使用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将在各种情况下进行完整的垃圾回收(例如,如果"在scavenge尝试中升级失败"),但根据该博客,它会记录完整GC的原因。
相反,我看到了临时的完整GC。它肯定是CMS,因为有其他CMS日志条目。
是否有理由进行完整的GC,但不记录原因?
编辑: 抱歉,有多个Java安装程序(我继承了这个设置)。实际上它使用jdk1.6.0_27。
编辑 不幸的是,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 

你能告诉我们你正在使用哪些JVM参数吗? - Paul Medcraft
我认为Java 5.0不支持“-XX:+UseCompressedOops”。 - Peter Lawrey
你需要添加-verbose:gc以获取更多关于正在发生的情况的信息。 - Matt
1个回答

2
ConcurrentMarkSweepGC将在即将填满或达到低水位标记时进行垃圾回收。(我不认为这是本例的情况)更有可能的是,某些代码直接调用System.gc()。例如,默认情况下,RMI会每小时调用它。您可以尝试使用-XX:+DisableExplicitGC来查看是否有所改善。如果确实如此,我会追踪原因并阻止其发生(有些人只是保留此选项)。另一个可能的原因是剩余直接内存不足。直接内存仅在GC时清理,但对堆大小没有太大贡献,因此似乎需要进行GC。当直接内存用完时,必须调用System.gc()来释放使用它的ByteBuffer。我解决这个问题的方法是显式地清理直接和内存映射的ByteBuffer,以避免用尽。此外,我建议尝试Java 6更新30甚至Java 7更新2,因为它可能具有更可预测的行为(即使您不能使用它,它也可能很有帮助)。您可以尝试使用命令来查看触发了哪个GC(但并非总是有效)。
`jstat -gccause {pid} 10s`

嗨,谢谢。我已经使用-XX:+DisableExplicitGC启用了程序,所以我猜这不是RMI的问题。什么是“直接内存”?谷歌最接近的答案是“直接缓冲区内存”,它是同一个东西吗?那么System.gc()不使用并发GC(由-XX:+UseConcMarkSweepGC指定),而是强制使用普通GC吗? - Mark
system.gc() 将触发一个非计划的完整 GC,因此它不会是并发的,并且将是完全的 STW 暂停。 - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接