老年代堆已满,伊甸园区和幸存者区域空间不足且几乎为空。

22

最近一个生产环境变得非常缓慢。进程的CPU占用率达到了200%。但进程仍在不断工作。在我重启服务后,它恢复了正常。我有几个症状: Par Survivor空间堆长时间为空,垃圾收集占用了约20%的CPU时间。

JVM选项:

X:+CMSParallelRemarkEnabled, -XX:+HeapDumpOnOutOfMemoryError, -XX:+UseConcMarkSweepGC, -                XX:+UseParNewGC, -XX:HeapDumpPath=heapdump.hprof, -XX:MaxNewSize=700m, -XX:MaxPermSize=786m, -XX:NewSize=700m, -XX:ParallelGCThreads=8, -XX:SurvivorRatio=25, -Xms2048m, -Xmx2048m

     Arch   amd64
     Dispatcher Apache Tomcat
     Dispatcher Version 7.0.27
     Framework  java
     Heap initial (MB)  2048.0
     Heap max (MB)  2022.125
     Java version   1.6.0_35
    Log path    /opt/newrelic/logs/newrelic_agent.log
    OS  Linux
    Processors  8
    System Memory   8177.964, 8178.0

附图中有更多信息。当非堆出现问题时,已使用的代码缓存和已使用的cms perm gen减少了一半。

我从newrelic获取了这些信息。enter image description here

问题是为什么服务器开始变得如此缓慢。

有时服务器完全停止,但我们发现PDFBox存在问题。上传某些包含某些字体的pdf时会崩溃JVM。

更多信息:我观察到每天Old gen都在填充。现在我每天重启服务器。重启后状态很好,但Old gen会在下一天继续填充,并且服务器会变慢,直到需要重新启动。


1
那么,问题是什么? - Frank Pavageau
如果永久空间已经用尽,新空间几乎为空,那么将新空间的大小减小并将更多的空间分配给永久代是有意义的,如果你这样做后还遇到相同的问题,那么可能存在内存泄漏。 - TMN
perm包含编译后的类和其他一些内容。我看到的问题是老年代正在累积。我每天都必须重新启动服务器才能恢复正常。当perm gen图形(以及其余部分)下降时,就会重启tomcat。 - Bogdan
1个回答

27

CMS默认在OldGen达到70%时开始并发收集。如果它无法在此边界以下释放内存,它将永久并发运行,这会显著减慢操作速度。如果OldSpace接近满载,OldGen使用率将恐慌并回退到停止-全球GC暂停,这可能非常长(如20秒)。

您可能需要更多的OldGen空间(确保应用程序不泄漏内存!)。另外,您可以通过以下方式降低启动并发收集的阈值(默认为70%):

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=50

这将触发从50%占用开始的并发收集,并增加CMS及时完成GC的机会。这只有在您的分配率过高时才会有所帮助,从您的图表中看起来是由于OldGen空间不足/内存泄漏和XX:CMSInitiatingOccupancyFraction过高导致的。请至少为OldGen空间增加500MB到1GB。


1
问题已经解决了。谢谢。我们增加了1GB的容量,现在没有任何问题了。 - Bogdan

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