Java中的PermGen错误,而内存使用率很低

Java应用程序有时死于PermGen空间错误,但是当我查看内存使用情况时,从我所知道的情况来看,它似乎很低。

这是一个Tomcat应用程序,再加上运行SOLR服务器(在同一个tomcat下)。

catalina.sh JVM参数:

 -Xms1024m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/logs 

catalina.out出错:

 java.lang.OutOfMemoryError: PermGen space Dumping heap to /path/to/logs/java_pid22335.hprof ... Heap dump file created [107041478 bytes in 1.823 secs] Exception in thread "pool-5-thread-1" java.lang.OutOfMemoryError: PermGen space 

现在第一个奇怪的是内存转储只有100Mb,而堆的限制是2048Mb。 当我使用“正确的”内存不足错误时,转储文件的大小接近于堆的限制。

第二件奇怪的事情是由jmap -heap 22335显示的内存使用情况 – jmap -heap 22335似乎很正常(当这个命令运行的Java应用程序仍然下来):

 Attaching to process ID 22335, please wait... Debugger attached successfully. Server compiler detected. JVM version is 11.3-b02 using thread-local object allocation. Parallel GC with 16 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2147483648 (2048.0MB) NewSize = 2686976 (2.5625MB) MaxNewSize = -65536 (-0.0625MB) OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 88080384 (84.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 566689792 (540.4375MB) used = 13467648 (12.84375MB) free = 553222144 (527.59375MB) 2.3765467792297907% used From Space: capacity = 327680 (0.3125MB) used = 0 (0.0MB) free = 327680 (0.3125MB) 0.0% used To Space: capacity = 327680 (0.3125MB) used = 0 (0.0MB) free = 327680 (0.3125MB) 0.0% used PS Old Generation capacity = 1431699456 (1365.375MB) used = 86216248 (82.22222137451172MB) free = 1345483208 (1283.1527786254883MB) 6.021951579200712% used PS Perm Generation capacity = 88080384 (84.0MB) used = 88080080 (83.99971008300781MB) free = 304 (2.899169921875E-4MB) 99.99965486072358% used 

我看着内存转储文件,没有什么不寻常的。 试图增加堆的限制,没有区别。

任何想法可能是什么,为什么转储文件是如此之小,同时应用程序继续抛出内存错误的内存使用情况?

 PS Perm Generation capacity = 88080384 (84.0MB) used = 88080080 (83.99971008300781MB) free = 304 (2.899169921875E-4MB) 99.99965486072358% used 

有你的罪魁祸首 PermGen用于类定义,而且你似乎有很多!

尝试通过添加到Tomcat启动选项启动您的PermGen大小:

 -XX:MaxPermSize=256M 

…但是如果你的应用程序被粉碎到你目前的限制,这个改变只会给你一些额外的崩溃时间。

监视它的行为,以及使用率增长的速度,但是准备在应用程序代码中进行问题类定义的挖掘。

最大PermGen大小由单独的命令行开关设置,请尝试-XX:MaxPermSize=128M ,这对PermGen应该足够了。