2016-07-26 2 views
1

Я использую CMS для GC, однако использование процессора будет очень высоким каждые два месяца.Настройка параметров для GC (CMS)

Есть одна часть журнала GC, когда ситуация ухудшилась, вы можете найти длинный STW.

3519696.386: [GC [1 CMS-initial-mark: 8617524K(12582912K)] 17105967K(23907584K), 4.9369140 secs] [Times: user=4.94 sys=0.00, real=4.94 secs] 
3519701.324: [CMS-concurrent-mark-start] 
3519709.419: [CMS-concurrent-mark: 8.096/8.096 secs] [Times: user=16.17 sys=0.00, real=8.09 secs] 
3519709.420: [CMS-concurrent-preclean-start] 
3519709.442: [CMS-concurrent-preclean: 0.023/0.023 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
3519709.442: [CMS-concurrent-abortable-preclean-start] 
CMS: abort preclean due to time 3519714.691: [CMS-concurrent-abortable-preclean: 3.345/5.248 secs] [Times: user=3.36 sys=0.00, real=5.25 secs] 
3519714.692: [GC[YG occupancy: 8489655 K (11324672 K)]3519714.692: [Rescan (parallel) , 8.4072250 secs]3519723.099: [weak refs processing, 0.0000190 secs]3519723.099: [scrub string table, 0.0008130 secs] [1 CMS-remark: 8617524K(12582912K)] 17107180K(23907584K), 8.4081940 secs] [Times: user=65.71 sys=0.15, real=8.41 secs] 
3519723.100: [CMS-concurrent-sweep-start] 
3519725.451: [CMS-concurrent-sweep: 2.350/2.350 secs] [Times: user=2.36 sys=0.00, real=2.35 secs] 
3519725.451: [CMS-concurrent-reset-start] 
3519725.478: [CMS-concurrent-reset: 0.028/0.028 secs] [Times: user=0.03 sys=0.00, real=0.03 secs] 
3519727.480: [GC [1 CMS-initial-mark: 8617522K(12582912K)] 17107229K(23907584K), 4.9378950 secs] [Times: user=4.94 sys=0.00, real=4.94 secs] 
3519732.418: [CMS-concurrent-mark-start] 

Мои параметры GC:

java -server -Xmx24g -Xms24g -XX:NewSize=12g -XX:MaxNewSize=12g -XX:+HeapDumpOnOutOfMemoryError -XX:MaxDirectMemorySize=24g -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:ReservedCodeCacheSize=128m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:CMSInitiatingOccupancyFraction=68 

Есть 9 процессоров и установлен 64G памяти на моем сервере.

Не могли бы вы помочь выяснить, почему он становится хуже ежемесячно?

+0

Подключены ли вы визуально, если у вас есть проблема с утечкой или финализацией? –

+0

@ ThorbjørnRavnAndersen Есть ли какие-нибудь инструменты для его создания? – Junjie

+0

Visualvm является частью дистрибутива jdk. –

ответ

4

Хорошо, давайте посмотрим немного подробнее. Во-первых, я хочу отметить, что все время, похоже, работает с пользователем, а не с sys, поэтому основными подозреваемыми являются JVM и приложение.

GC запускается в старых поколениях. занятость 8617524K вместимостью 12582912K. Общее использование кучи 17105967K, размер 23907584K.

Начальная отметка занимает ~ 5 с.

3519696.386: [GC [1 CMS-initial-mark: 8617524K(12582912K)] 17105967K(23907584K), 4.9369140 secs] [Times: user=4.94 sys=0.00, real=4.94 secs] 

AFAIK начальная отметка обрабатывает только GC-корни. Вы можете видеть, какие из них here, но тот факт, что он принимает так много, является странным. Мое первое подозрение было бы, что это зависит от времени к safepoints, поэтому, возможно, позволит:

-XX: + PrintSafepointStatistics -XX: PrintSafepointStatisticsCount = 1

Параллельной фаза метки принимает 8s

3519709.419: [CMS-concurrent-mark: 8.096/8.096 secs] [Times: user=16.17 sys=0.00, real=8.09 secs] 

это сканирование живых объектов

Preclean сравнительно быстро.

Abortable preclean отменяется в 5 секунд, который поставляется AFAIK, настраивается с CMSMaxAbortablePrecleanTime. Копая эту опцию, я вижу, что наличие небольших коллекций на этом этапе желательно, и отказ сделать это может привести к переменным большим паузам в CMS. Увеличение этого CMSMaxAbortablePrecleanTime и активация CMSScavengeBeforeRemark. Отметьте эту запись: Jon Masamitsu.

Молодое поколение находится на 8G, а повторное сканирование занимает 8 секунд, что кажется слишком большим. Снова тот же комментарий re. safepoints.

3519714,692: [GC [YG размещение: 8489655 К (11324672 К)] +3519714,692: [Пересканировать (параллельно), 8.4072250 сек] +3519723,099: [слабый обработка рефов, 0.0000190 сек] +3519723,099: [скраб строка таблицы, 0.0008130 сек] [1 CMS-примечание: 8617524K (12582912K)] 17107180K (23907584K), 8.4081940 secs] [Times: user = 65,71 sys = 0,15, real = 8,41 secs]

Обратите внимание, что молодой ген. фактически увеличился за этот период: 8617524K

Окончательная очистка при параллельной развертке занимает 2,35 секунды, а содержимое кучи существенно не изменяется. У вас все еще есть примерно то же самое молодое и кучное использование.

Так резюмируя я вижу два момента:

  • Ваша куча большие, вы достигающие CMSInitiatingOccupancyFraction и запускающие CMS, и много времени, как представляется, происходит сканирование живых объектов. В любом случае, проверьте время, чтобы узнать, можно ли улучшить это.
  • GC действительно не собрать так, вы, вероятно, в одной из этих ситуаций:
    • Вы хотите сохранить много долгоживущих объектов (например .: Кэш-память). В этом случае вы хотите увеличить CMSInitiatingOccuppancyFraction (так как вы ожидаете, что старый ген станет очень полным). Но также наблюдайте, что вы не рекламируете какие-либо средние или короткоживущие объекты, потому что они в конечном итоге (через день или через 2 месяца) приведут к длительным GC. То есть: избегайте отторжения в старых поколениях.
    • Вы создаете много объектов с короткой серединой, вам нужно избегать рекламных акций. Уменьшите ассигнования, увеличьте Иден.

Все более подробную информацию о приложении, и т.д., безусловно, поможет гвоздь вниз лучше. Надеюсь, это поможет.

1

В ваших журналах я не вижу нормального молодого GC. Фазы CMS Stop-the-World рассчитаны на то, чтобы обеспечить эффективную передачу молодых космических снимков.

3519727.480: [GC [1 CMS-initial-mark: 8617522K(12582912K)] 17107229K(23907584K), 4.9378950 secs] [Times: user=4.94 sys=0.00, real=4.94 secs] 

Здесь CMS-initial-mark должны сканировать 8.6 контрклин молодого пространства в одном потоке. Если бы это было вызвано сразу после молодого юниора, то занятие на молодой земле было бы на порядок меньше.

То же самое верно для CMS-remark.

Молодые люди имеют большое молодое пространство, поэтому вы попадаете в ситуацию, когда вы старое пространство собираете чаще, чем молодое пространство.

Вот несколько вариантов, чтобы исправить это

  • -XX:CMSWaitDuration=3600000 пусть CMS-initial-mark ждать до одного часа до следующего молодого GC.
  • -XX:+CMSScavengeBeforeRemark let CMS-remark сила молодая коллекция, чтобы произвести предсказуемое время паузы.
  • Используйте последние Java 7/8, который имеет параллельные CMS-initial-mark

Более подробную информацию можно получить в this article.

Смежные вопросы