老Gen堆已经满了,Eden和Survivor很低,几乎是空的

时间:2013-10-16 13:03:42

标签: java garbage-collection jvm

最近生产环境变得非常缓慢。该过程的CPU占了200%。它继续工作。重新启动服务后,它再次正常运行。我有几个症状:    Par幸存者空间堆很长时间是空的,垃圾收集占用了大约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每天都在填满。现在我每天重启服务器。重新启动之后,这一切都很好,花花公子,但旧的一直在填补,直到第二天,服务器速度减慢,直到需要重新启动。

1 个答案:

答案 0 :(得分:25)

默认情况下,如果OldGen为70%,CMS会同时开始收集。如果它不能释放低于此边界的内存,它将永久并发运行,这将显着减慢操作。如果OldSpace接近完全使用OldGen,它将会出现恐慌并回落到停止世界的GC暂停,这可能会很长(例如20秒)。 您可能需要在OldGen中有更多的空间(确保您的应用程序不会泄漏内存!)。此外,您可以使用

降低阈值以启动并发收集(默认为70%)

-XX:+ UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction = 50

这将触发以50%占用率开始的并发收集,并增加CMS及时完成GC的机会。这只会在你的分配率太高的情况下有所帮助,从你的图表看起来不够 - headrooom / memleak +太高XX:CMSInitiatingOccupancyFraction。提供至少500MB到1GB的OldGen空间