JVM Tenured / Old gen достиг лимита и зависание сервера - PullRequest
22 голосов
/ 09 мая 2011

Наше приложение требует очень большой памяти, поскольку оно работает с очень большими данными.Следовательно, мы увеличили наш максимальный размер кучи до 12 ГБ (-Xmx).

Ниже приведены подробные сведения об окружении

OS - Linux 2.6.18-164.11.1.el5    
JBoss - 5.0.0.GA
VM Version - 16.0-b13 Sun JVM
JDK - 1.6.0_18

Мы имеем выше env & configuration в нашем QA & prod.В QA у нас максимум PS Old Gen (Heap memory) выделен как 8,67 ГБ, тогда как в Prod это всего 8 ГБ.

В Prod для конкретной работы Old Gen Heap достигает 8 ГБ, зависает там и веб-URL становятся недоступными,Сервер выходит из строя.Но в QA он также достигает 8,67 ГБ, но полный GC выполняется и возвращается к 6,5 ГБ или что-то еще.Здесь это не зависает.

Мы не могли найти решение для этого, потому что и среда, и конфигурация на обоих блоках одинаковы.

У меня 3 вопроса здесь,

2/3-я часть максимальной кучи будет выделена старому / постоянному поколению.Если это так, почему это 8 ГБ в одном месте и 8,67 ГБ в другом месте?

Как обеспечить правильное соотношение для Нового и срока пребывания в этом случае (12 ГБ)?

Почему этополный GCed в одном месте, а не в другом?

Любая помощь будет действительно заметной.Спасибо.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация о env или conf.

Ответы [ 2 ]

22 голосов
/ 10 мая 2011

Для ваших конкретных вопросов:

  1. Соотношение по умолчанию между новым и старым поколениями может зависеть от системы, и то, что JVM определит, будет наилучшим.
  2. Чтобы указать конкретное соотношение между новым и старым поколениями с помощью -XX:NewRatio=3.
  3. Если ваша JVM зависает и куча заполнена, она, вероятно, застревает, выполняя постоянные GC.

Похоже, вам нужно больше памяти для производства. Если в QA запрос завершается, то, возможно, дополнительные 0,67 ГБ - это все, что ему нужно. Это, кажется, не оставляет вам большой запас. Вы проводите тот же тест на QA, что и на Prod?

Поскольку вы используете 12 ГБ, вы должны использовать 64-разрядную. Вы можете сэкономить память 64-битной адресации, используя опцию -XX:+UseCompressedOops. Обычно это экономит 40% памяти, поэтому ваши 12 ГБ пойдут намного дальше.

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

-Xmx12g -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC
-XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled
-XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68
3 голосов
/ 10 мая 2011

вам нужно получить больше данных, чтобы знать, что происходит, только тогда вы узнаете, что нужно исправить.На мой взгляд, это означает, что

  1. получить подробную информацию о том, что делает сборщик мусора, эти параметры - хорошее начало (вместо gc.log вместо файла gc.log следует указать какой-нибудь предпочтительный путь и файл)

    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:gc.log -verbose:gc

  2. повторить прогон, отсканировать журнал gc за период, когда он зависает, и отправить с этим выводом

  3. рассмотрите возможность просмотра вывода с использованием visualgc (требуется, чтобы на сервере был запущен jstatd, одна случайная ссылка, объясняющая, как выполнить эту настройку, эта ), которая является частью jvmstat , thisЭто простой способ увидеть, как измеряются различные поколения в куче (хотя, возможно, не в течение 6 часов!)

Я также настоятельно рекомендую вам кое-что почитать, чтобы вы знали, что все этопереключатели имеют в виду иначе вы будете слепо пробовать вещи без реального понимания того, почему одна вещь помогает, а другая нет.Я бы начал со страницы настройки oracle java 6 gc, которую вы можете найти здесь

Я бы предложил изменять параметры только после того, как вы добились базовой производительности.Сказав, что CompressedOops v скорее всего будет легким выигрышем, вы можете заметить, что по умолчанию он включен с 6u23.

Наконец, вы должны рассмотреть вопрос об обновлении jvm, 6u18 немного встает ипроизводительность продолжает улучшаться.

выполнение каждого задания занимает 3 часа, и почти 6 заданий выполняются одно за другим.Последнее задание при запуске достигает 8 ГБ макс и зависает в prod

Эти задания вообще связаны?это действительно звучит как постепенная утечка памяти, если они не работают с одним и тем же набором данных.Если использование кучи продолжает увеличиваться и в конечном итоге вылетает, значит, у вас утечка памяти.Вы должны рассмотреть возможность использования -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/some/dir для захвата дампа кучи (хотя обратите внимание, что с кучей 13G это будет большой файл, поэтому убедитесь, что у вас есть место на диске), если / когда он дует.Затем вы можете использовать jhat , чтобы посмотреть, что было в куче в то время.

...