Подтвердить что ты не робот

JVM Tenured/Old gen достиг предела и сервера висит

Наше приложение требует очень большой памяти, поскольку оно имеет дело с очень большими данными. Следовательно, мы увеличили максимальный размер кучи до 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 и конфигурации в нашем QA и prod. В QA мы имеем максимальный PS Old Gen (память кучи), выделенный как 8.67GB, тогда как в Prod это всего 8GB.

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

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

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

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

Как обеспечить допустимый коэффициент для New и Владение в этом случае (12 ГБ)?

Почему он заполнен GCed в одном месте и не в другом?

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

Pls сообщит мне, если вам нужна дополнительная информация по env или conf.

4b9b3361

Ответ 1

По вашим конкретным вопросам:

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

Похоже, вам нужно больше памяти для prod. Если на 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

Ответ 2

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

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

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

  • повторите прогон, просмотрите журнал gc в течение периода, когда он висит и отправляет обратно с этим выходом

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

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

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

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

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

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