Приложение Java время от времени умирает из-за ошибки пространства PermGen, но когда я смотрю на использование памяти, оно кажется низким, насколько я могу судить.
Это приложение Tomcat, плюс работает сервер SOLR (под тем же tomcat).
Параметры JVM в catalina.sh
:
-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
Теперь первая странность заключается в том, что дамп памяти составляет всего 100 МБ, а ограничение кучи - 2048 МБ. Когда у меня возникали «правильные» ошибки нехватки памяти, размер файла дампа был близок к пределу кучи.
Вторая странность - это использование памяти, показанное 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 используется для определений классов, и у вас их, кажется, много!
Попробуйте увеличить размер PermGen, добавив это в параметры запуска Tomcat:
-XX:MaxPermSize=256M
... но если ваше приложение превышает ваш текущий лимит, это изменение даст вам лишь дополнительное время между сбоями.
Следите за тем, как оно ведет себя и как быстро растет его использование, но будьте готовы покопаться в коде вашего приложения, чтобы найти определения классов проблем.
Максимальный размер PermGen устанавливается отдельным переключателем командной строки, попробуйте -XX:MaxPermSize=128M
, этого должно хватить для PermGen.