老将军堆满了,伊甸园和幸存者很低,几乎是空的

2022-09-02 01:33:01

最近,生产环境变得非常缓慢。进程的 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崩溃。

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


答案 1

默认情况下,如果 OldGen 为 70%,CMS 将开始并发收集。如果它无法释放此边界以下的内存,它将永久并发运行,这将大大减慢操作速度。如果OldSpace接近完全使用OldGen,它将惊慌失措并回落到停止世界GC暂停,这可能很长(如20秒)。您可能需要在OldGen中有更多的余量(确保您的应用程序不会泄漏内存ofc!此外,还可以降低阈值以启动并发收集(默认为 70%),使用

-XX:+UseCMSInitiatingOccupancy Only -XX:CMSInitiatingOccupancyFraction=50

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


答案 2