Что заставляет память tomcat расти и падать
Память Tomcat
Ответ 1
Именно сам jconsole вызывает шаблон zig zag.
Чтобы увидеть эффект jconsole
или jvisualvm
вы можете написать простую java-программу только с основным контуром. Например
public static void main(String[] args) {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
Выполните его только с небольшой кучей java -Xmx20m...
Это поможет вам лучше увидеть использование кучи, потому что инструмент jstat
я буду использовать далее, печатает использование в процентах.
Теперь откройте окно командной строки и выполните jstat
. Вам понадобится PID java-процесса и вы сможете найти его с помощью jps -l
.
jstat -gcutil <PID>
он распечатает что-то вроде этого
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 0,00 69,34 0,00 14,48 17,19 0 0,000 0 0,000 0,000
Сосредоточьтесь на Эдем пространстве E
. Значение представляет собой процентное значение емкости пространства. Посмотрите на jstat для деталей.
Если вы выполните команду снова и снова, вы увидите, что использование пространства eden не будет расти. Он сохраняется, например, на уровне 69,34
. Я использую команду linux watch, например, в моих окнах, чтобы перезапустить команду с определенным интервалом. Смотрите watch.bat
Теперь откройте jconsole
jconsole <PID>
и выполнить команду jstat
снова и снова. Вы увидите, что пространство eden постоянно растет до тех пор, пока макс не будет достигнуто, и это сбор мусора.
Вот мой вывод jstat --gcutil <PID>
с интервалом в 1 секунду. Сосредоточьтесь на Эдем пространстве E
.
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 0,00 67,42 0,00 14,48 17,19 0 0,000 0 0,000 0,000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 0,00 67,42 0,00 14,48 17,19 0 0,000 0 0,000 0,000
# jconsole connected
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 81,64 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 84,66 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 89,70 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 91,70 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 93,70 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 95,70 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 96,70 7,57 92,26 84,87 1 0,001 0 0,000 0,001
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 96,88 98,71 7,57 92,26 84,87 1 0,001 0 0,000 0,001
# Garbage collected
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
100,00 0,00 1,13 14,06 94,75 89,26 2 0,003 0 0,000 0,003
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
100,00 0,00 3,00 14,06 94,75 89,26 2 0,003 0 0,000 0,003
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
100,00 0,00 5,75 14,06 94,75 89,26 2 0,003 0 0,000 0,003
Как вы можете видеть... После того, как jconsole подключился к процессу, пространство eden растет и растет, пока не собрано мусор. Это приводит к созданию зигзагообразного рисунка. Вот снимок от jvisualvm
.
Вы обнаружите аналогичное поведение, когда будете делать то же самое с процессом tomcat. Единственным отличием будет то, что пространство eden растет очень немного, даже если никакой jconsole не подключен. Но этот незначительный рост не является причиной для зигзагообразного рисунка, который вы видите.
Вот результат jstat
для моего tomcat.
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,33 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,33 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,43 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,43 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,43 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
этот выход продолжается в течение 36 секунд, пока вы не увидите небольшое изменение памяти. От 70,43
до 70,53
.
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,43 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,53 4,81 96,85 90,10 5 0,037 0 0,000 0,037
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0,00 99,80 70,53 4,81 96,85 90,10 5 0,037 0 0,000 0,037
Таким образом, это небольшое изменение - единственное, за что отвечают фоновые процессы tomcat.
PS: Вы также можете время от времени использовать Memory Analyzer и дайверы кучи памяти, и вы увидите, что количество используемой памяти для byte[]
увеличивается, из-за сетевого трафика RMI.
Ответ 2
Вот важные моменты, чтобы понять шаблон zig zag, объясненный в связанном ответе:
- Когда коллекционер запускает его сначала пытается частичный сбор только освобождает память, которая была выделена недавно
- недавно созданные объекты, которые все еще активны, получают "продвижение"
- Как только объект будет продвинут несколько раз, он больше не будет очищен частичными коллекциями даже после того, как он будет готов к сбору
- Эти объекты, называемые tenured, очищаются только тогда, когда требуется полная сборка, чтобы сделать достаточно места для продолжения работы программы
Вопрос: Что заставляет память расти так, даже когда приложение полностью не работает?
Ответ. Есть внутренние запланированные задания, такие как автоматизация, таймеры и т.д. Или некоторый внешний мониторинг процесса, который вызывает рост памяти, когда приложение простаивает. Возможно, ваше приложение имеет одинаковое количество объектов, но некоторые могут быть больше. Например, у вас может быть несколько ArryList
и некоторый StrigBuilder
который продолжает увеличивать кеш.
Источники:
Ответ 3
http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html Чтобы начать, вот полезная ссылка на "Tuning Garbage Collection с виртуальной машиной 5.0 Java TM",
Это звучит как пауза GC, делающая tomcat невосприимчивой. Прежде всего, это сборщик мусора "с низкой паузой" с опцией -XX: + UseConcMarkSweepGC.
Ответ 4
См. График Около 12: 08, Размер рабочей памяти максимальный (199 МБ).
Примерно в 12:09 сборщик мусора работает, мертвый объект собран, размер рабочей памяти составляет около 145 МБ.
Примерно в 12:12 рабочая память увеличилась, появилось много мертвых объектов, увеличение памяти с 145 МБ → 155 МБ → 165 МБ → 180 МБ ->... → 190 МБ.
Примерно в 12: 13 сборщик мусора снова работает, мертвый объект собирается, размер рабочей памяти составляет около 145 МБ.
...и так далее. Фактически, это периодический график, если не происходит особых событий.
Ответ 5
Причины могут быть разными, без дополнительной информации о вашем приложении: если он не выполняет какую-либо повторяющуюся задачу самостоятельно, одной из возможных причин может быть сама JConsole, поскольку сбор информации и ее передача через RMI потребляет память, которую можно быстро собрать из Eden пространство.
Вы можете проверить это предположение путем профилирования с помощью менее "навязчивого" инструмента (например, включения вывода подробной документации GC с -verbosegc
) и сравнения профилей использования памяти в аналогичных настройках.
Как указано в других ответах, Tomcat может иметь свои собственные накладные расходы. Вы можете проверить это другое предположение, слушая сервлет "привет, мир" и сравнивая потребление памяти этих двух с аналогичным инструментом.