Java ConcurrentMarkSweep сборщик мусора не происходит - PullRequest
1 голос
/ 10 января 2012

Детали среды: ОС: Linux RedHat Java: обновление JRE 6 21

Я использую следующие настройки GC для моего приложения.

-server -d64 -Xms8192m -Xmx8192m -javaagent:lib/instrum.jar -XX\:MaxPermSize=256m -XX\:+UseParNewGC -X\:+ParallelRefProcEnabled -XX\:+UseConcMarkSweepGC -XX\:MaxGCPauseMillis=250 -XX\:+CMSIncrementalMode -XX\:+CMSIncrementalPacing -XX\:+CMSParallelRemarkEnabled -verbose\:gc -Xloggc\:/tmp/my-gc.log -XX\:DisableExplicitGC -XX\:+PrintGCTimeStamps -XX\:+PrintGCDetails -XX\:+UseCompressedOops

При наличии этой настройки в начале приложения есть один Full GC

2.946: [Full GC 2.946: [CMS: 0K->7394K(8111744K), 0.1364080 secs] 38550K->7394K(8360960K), [CMS Perm : 21247K->21216K(21248K)], 0.1365530 secs] [Times: user=0.10 sys=0.04, real=0.14 secs] 

За которым следует 4-5 успешных коллекций CMS, но после этого нет следов CMS в журналах, есть записи только в второстепенных коллекциях.

379022.293: [GC 379022.293: [ParNew: 228000K->4959K(249216K), 0.0152000 secs] 7067945K->6845720K(8360960K) icms_dc=0 , 0.0153940 secs]

Куча постоянно растет и достигла 7 ГБ. Мы должны перезапустить приложение, поскольку мы не можем позволить себе OOM или какой-либо сбой в производственной системе.

Я не могу понять, почему коллектор CMS прекратил очистку. Любые подсказки / предложения приветствуются. Заранее спасибо.

=============================================== ======================================= Обновлено 23 января.

Спасибо всем за ответы до сих пор. Я настроил приложение в тестовой среде и протестировал приложение со следующим набором параметров JVM:

Вариант № 1

-server -d64 -Xms8192m -Xmx8192m -javaagent\:instrum.jar -XX\:MaxPermSize\=256m -XX\:+UseParNewGC -XX\:+UseConcMarkSweepGC -verbose\:gc -Xloggc\:my-gc.log -XX\:+PrintGCTimeStamps -XX\:+PrintGCDetails

Вариант № 2

-server -d64 -Xms8192m -Xmx8192m -javaagent\:instrum.jar -XX\:MaxPermSize\=256m -XX\:+UseParNewGC -XX\:+UseConcMarkSweepGC -verbose\:gc -Xloggc\:my-gc.log -XX\:+DisableExplicitGC -XX\:+PrintGCTimeStamps -XX\:+PrintGCDetails

Я провел тест с обоими настройками в течение 2 дней параллельно. Вот мои наблюдения:

Вариант № 1 Память кучи стабильна, но имеется 90 коллекций ConcurrentMarkSweep и JVM потратила 24 минуты. Это слишком высоко. И я вижу следующие строки в журналах GC, и шаблон продолжается каждый час ...

318995.941: [GC 318995.941: [ParNew: 230230K->8627K(249216K), 0.0107540 secs] 5687617K->5466913K(8360960K), 0.0109030 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
319050.363: [GC 319050.363: [ParNew: 230195K->9076K(249216K), 0.0118420 secs] 5688481K->5468316K(8360960K), 0.0120470 secs] [Times: user=0.12 sys=0.01, real=0.01 secs]
319134.118: [GC 319134.118: [ParNew: 230644K->8503K(249216K), 0.0105910 secs] 5689884K->5468704K(8360960K), 0.0107430 secs] [Times: user=0.11 sys=0.00, real=0.01 secs]
319159.250: [Full GC (System) 319159.250: [CMS: 5460200K->5412132K(8111744K), 19.1981050 secs] 5497326K->5412132K(8360960K), [CMS Perm : 72243K->72239K(120136K)], 19.1983210 secs] [Times: user=19.14 sys=0.06, real=19.19 secs]

Я не вижу одновременных меток и журналов развертки. Означает ли это, что CMS переключена на сборщик пропускной способности? Если так, почему?

Вариант № 2:

Поскольку я вижу журналы Full GC (System), я подумал о добавлении -XX \: + DisableExplicitGC. Но с этой опцией сбор не происходит, и текущий размер кучи составляет 7.5G. Что мне интересно, так это то, почему CMS выполняет полный сборщик мусора вместо одновременного сбора.

Ответы [ 4 ]

1 голос
/ 13 января 2012

CMS работает для вас: P

Вы используете инкрементный режим в CMS (хотя на самом деле вам не стоит беспокоиться, так как это может повредить вашей пропускной способности)

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

Эта часть вашего журнала относится к параллельному новому (количество раздач - размер кучи)

379022.293: [GC 379022.293: [ParNew: 228000K->4959K(249216K), 0.0152000 secs]

эта часть является инкрементальной CMS (iCMS)

7067945K->6845720K(8360960K) icms_dc=0 , 0.0153940 secs]

Я бы спросил, почему вы используете iCMS, у вас много ссылок Soft / Weak / Phantom (или почему вы используете флаг ParallelRefProcEnabled), и вы на самом деле видели нехватку памяти? или невыносимая пауза.

Попробуйте вернуться к CompressedOops, ParNewGC и CMS без каких-либо дополнительных действий и посмотрите, сработает ли это для вас.

1 голос
/ 10 января 2012

Это теория ...

Я подозреваю, что эти коллекции CMS не были полностью успешными. Событие в 12477.056 выглядит так, как будто CMS, возможно, решила, что не сможет работать должным образом из-за слишком долгого шага «предварительной очистки».

Если это заставило CMS принять решение об отключении, то я ожидаю, что он вернется к использованию классического алгоритма GC с "пропускной способностью". И есть большая вероятность, что он подождет, пока куча не заполнится, а затем запустит полный сборщик мусора. Короче говоря, если бы вы просто позволили этому продолжаться, все было бы в порядке (по модулю, что вы будете время от времени получать большие паузы GC).


Я предлагаю вам запустить приложение на тестовом сервере с таким же размером кучи и другими параметрами GC и посмотреть, что произойдет, когда сервер достигнет предела. Это на самом деле выбрасывает OOME?

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

Когда вы устанавливаете максимальный размер, он немедленно выделяет этот объем виртуальной памяти.

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

У вас включено много опций (некоторые из них по умолчанию). Я предлагаю вам сократить до минимума.установить, что они могут иметь нечетные взаимодействия, когда вы включаете много.

Я бы начал с (при условии, что у вас есть Solaris)

-mx8g -javaagent:lib/instrum.jar -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -verbose\:gc -Xloggc\:/tmp/my-gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails

Параметры -server по умолчанию на компьютерах класса сервера, -XX:+UseCompressedOops является значением по умолчанию в последних версиях Java, а -XX:MaxGCPauseMillis=250 - просто подсказка.

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

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

Я вижу, что начальный размер кучи -Xms составляет: 8192 м, а максимальный размер кучи -Xmx8192 м, что может быть одной из причин, почему GC все еще ожидает начала очистки.Я бы посоветовал уменьшить размер кучи, а затем проверить, активируется ли GC.

...