我在一个tomcat实例上运行了一个Java webapp。在高峰时段,webapp每秒大约30页,通常大约15页。
我的环境是:
O/S: SUSE Linux Enterprise Server 10 (x86_64)
RAM: 16GB
server: Tomcat 6.0.20
JVM: Java HotSpot(TM) 64-Bit Server VM 1.6.0_14
JVM options:
CATALINA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m
-XX:+UseParallelGC
-Djava.awt.headless=true
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
JAVA_OPTS="-server"
经过几天的正常运行后,Full GC开始更频繁地发生,并且它成为应用程序可用性的严重问题。在tomcat重新启动之后,问题就会消失,但当然会在5到10天或30天后返回(不一致)。
重启之前和之后的完整GC日志位于http://pastebin.com/raw.php?i=4NtkNXmi
它显示重启前的日志,在6.6天的正常运行时间,因为完整的GC需要2.5秒,并且每隔约6秒发生一次。
然后它会在重新启动后显示一个日志,其中Full GC仅每5-10分钟发生一次。
当Full GCs出现时我使用jmap -dump:format=b,file=dump.hprof PID
进行了两次转储(我不确定在发生Full GC时是否完全正确,或者在2个Full GC之间),并在{ {3}}但在泄漏嫌疑人中没有得到任何有用的东西:
请注意,我从未收到OutOfMemoryError。
关于我接下来应该去哪看的任何想法?
答案 0 :(得分:6)
当我们遇到这个问题时,我们最终将其追溯到年轻一代太小。虽然我们给了很多公羊,但年轻一代并没有得到公平的分享。
这意味着小垃圾收集会更频繁地发生,并导致一些年轻的对象被移动到终身代,这意味着更大的垃圾收集。
尝试使用价值相当低的-XX:NewRatio
(例如2或3)并查看是否有帮助。
可以找到更多信息here。
答案 1 :(得分:4)
我已从-Xmx1024m
切换到-Xmx2048m
,问题就消失了。我现在有100天的正常运行时间。
答案 2 :(得分:3)
在您的情况下可能发生的事情是,您有很多物品比NewGen生命周期长一点。如果幸存者空间太小,他们会直接前往OldGen。 -XX:+PrintTenuringDistribution
可以提供一些见解。你的NewGen足够大,所以请尝试减少SurvivorRatio
。
另外,jconsole可能会提供更多关于你的记忆发生情况的视觉洞察,试试吧。
答案 3 :(得分:2)
除了调整JVM的各种选项之外,我还建议升级到VM的更新版本,因为后来的版本有更好的调优垃圾收集器(也没有尝试新的实验版)。
除此之外,如果(部分)确定为JVM分配更多内存可能会增加执行GC所需的时间,那么在使用整个16 GB内存和增加内存占用之间存在权衡点,因此您可以尝试双倍所有值,开始
Xms1024m -Xmx2048m -XX:PermSize = 256m -XX:MaxPermSize = 512m
此致
的Massimo