22

最近生产环境变得非常缓慢。进程的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中获取了信息。在此处输入图像描述

问题是为什么服务器开始工作这么慢。

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

更多信息:我观察到老一代每天都在填满。现在我每天都重新启动服务器。重新启动后,一切都很好,但老一代正在填满,直到第二天,服务器速度变慢,直到需要重新启动。

4

1 回答 1

27

默认情况下,如果 OldGen 为 70%,则 CMS 开始同时收集。如果它无法释放低于此边界的内存,它将永久并发运行,这将显着减慢运行速度。如果 OldSpace 接近 OldGen 的全部使用量,它会恐慌并回退到 stop-the-world GC 暂停,这可能会很长(比如 20 秒)。您可能需要在 OldGen 中留出更多空间(确保您的应用程序不会泄漏内存!)。此外,您可以使用以下方法降低启动并发收集的阈值(默认 70%)

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=50

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

于 2013-10-23T15:56:02.710 回答