Когда именно JVM генерирует ошибку OutOfMemoryError - PullRequest
16 голосов
/ 18 января 2012

Мы запускаем приложение Java, которое иногда «зависает», потому что какой-то поток использует почти всю кучу. Несмотря на то, что JVM выполняет Full GC, который длится более 60 секунд, приложение никогда не умирает с OutOfMemoryError.

Я прочитал из документации Java, что:

Сборщик пропускной способности выдает исключение нехватки памяти, если слишком много времени тратится на сборку мусора. Например, если JVM тратит более 98% общего времени на сборку мусора и восстанавливает менее 2% кучи, это приведет к нехватке памяти.

Я хотел бы получить дополнительную информацию о том, что означают эти 98% времени (каковы временные рамки?) И возможно ли снизить это значение, т. Е. Выдать OOME, если приложение проводит 90% времени в GC и не может освободить более 10% кучи.

Цель - убедиться, что приложение умрет (вместо выполнения только GC) с OOME, чтобы мы могли создать дамп на OOME.

Вот настройки памяти и GC, которые мы используем (ОС Solaris):

-Xms2048m -Xmx2048m \
-Xmn512m \
-XX:PermSize=256m 
-XX:MaxPermSize=256m \
-XX:+UseParNewGC 
-XX:ParallelGCThreads=16 \
-XX:+UseConcMarkSweepGC 
-XX:+CMSParallelRemarkEnabled \
-XX:+DisableExplicitGC \
-XX:+PrintGC 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps \
-XX:+PrintClassHistogram \
-Xloggc:/gcmonitor.log \
-XX:+HandlePromotionFailure \
-XX:SurvivorRatio=4 
-XX:TargetSurvivorRatio=90 
-XX:MaxTenuringThreshold=10 \
-XX:+UseTLAB 
-XX:TLABSize=32k 
-XX:+ResizeTLAB \
-XX:+UseMPSS \

Ответы [ 3 ]

4 голосов
/ 18 января 2012

Я хотел бы получить больше информации о том, что означают эти 98% времени (каковы временные рамки?)

Ответ на этот вопрос: Превышен предел накладных расходов ГХ предполагает, что это 1 минута.

возможно понизить это значение

Еще раз изучая вопрос, упомянутый выше, похоже, что вы можете использовать параметры GCTimeLimit и GCHeapFreeLimit.

3 голосов
/ 18 января 2012

Если вы только хотите заставить OOM получить побочный эффект от дампа кучи, теперь вы можете сделать это на работающем Java-процессе в любое время:

Найти процесс:

jps -v

Принудительный сброс

jmap -dump: file = heap.bin

Затем проанализируйте heap.bin в выбранном вами инструменте.

0 голосов
/ 19 января 2012

Интерактивное выполнение дампа кучи в OOME или с помощью jmap может привести к остановке JVM на несколько минут.Как правило, более эффективно использовать gcore для создания дампа ядра вручную, а затем использовать jmap для извлечения дампа кучи из ядра.

Я бы выделил больше кучи, посмотрим, поможет ли это решить проблему.Также будьте осторожны с чрезмерной настройкой GC - как правило, коллекторы имеют отличные значения по умолчанию, я рекомендую варианты только после Xloggc, если вы определили, что они значительно улучшают производительность GC на основе шаблонов распределения / хранения объектов вашего приложения.Потоки параллельного коллектора также могут быть слишком высокими, в зависимости от количества доступных аппаратных потоков.

Вы должны быть в состоянии определить схему использования кучи из журналов GC и определить, является ли это быстрым использованием одним потоком, выполняя операцию, которая быстро исчерпывает кучу, или более медленную модель «утечки»где много объектов продвигаются с течением времени, что приводит к тому, что постоянное поколение будет состязаться с небольшим количеством объектов, подходящих для сбора, - гистограммы также помогут.Eclipse MAT - лучший инструмент анализа IMO.Вот отличное место, чтобы начать, если вы не использовали его раньше:

http://kohlerm.blogspot.com/2009/07/eclipse-memory-analyzer-10-useful.html

...