Куча старого генерала полна, а Иден и Оставшийся в живых низки и почти пусты
Производственная среда в последнее время стала очень низкой. Процессу процесса потребовалось 200%. Однако он продолжал работать. После перезагрузки службы он снова функционировал нормально. У меня есть несколько симптомов: Куча памяти оставшегося в живых оставалась пустой в течение длительного времени, а сбор мусора занимал около 20% времени процессора.
Параметры 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
По умолчанию CMS начинает собирать одновременно, если OldGen составляет 70%. Если он не может освободить память ниже этой границы, он будет работать постоянно параллельно, что значительно замедлит работу. Если OldSpace приближается к полному использованию OldGen, он будет паниковать и возвращаться к остановке GC-паузы, которая может быть очень длинной (например, 20 секунд).
Вероятно, вам нужно больше запаса в OldGen (убедитесь, что ваше приложение не течет из памяти!). Кроме того, вы можете снизить пороговое значение для запуска параллельной коллекции (по умолчанию 70%), используя
-XX: + UseCMSInitiatingOccupancyOnly
-XX: CMSInitiatingOccupancyFraction = 50
это приведет к одновременному сбору, начиная с 50% занятости и увеличения шанса, что CMS закончит GC вовремя. Это поможет только в том случае, если ваш уровень распределения слишком высок, из ваших графиков он выглядит как не-достаточно-headrooom/memleak + слишком высокий XX: CMSInitiatingOccupancyFraction. Дайте не менее 500 МБ на 1 ГБ больше пространства OldGen