1. Обзор
В этом кратком руководстве мы познакомимся с несколькими различными способами получения размера кучи работающего Java-приложения.
2. джкмд
Чтобы найти информацию о куче и метапространстве работающего приложения Java, мы можем использовать утилиту командной строки jcmd
:
jcmd GC.heap_info
Во-первых, давайте найдем идентификатор процесса конкретного Java-приложения с помощью команды jps
:
$ jps -l
73170 org.jetbrains.idea.maven.server.RemoteMavenServer36
4309 quarkus.jar
12070 sun.tools.jps.Jps
Как показано выше, идентификатор процесса для нашего приложения Quarkus — 4309. Теперь, когда у нас есть идентификатор процесса, давайте посмотрим информацию о куче:
$ jcmd 4309 GC.heap_info
4309:
garbage-first heap total 206848K, used 43061K
region size 1024K, 43 young (44032K), 3 survivors (3072K)
Metaspace used 12983K, capacity 13724K, committed 13824K, reserved 1060864K
class space used 1599K, capacity 1740K, committed 1792K, reserved 1048576K
Это приложение использует алгоритм G1 или алгоритм сборки мусора :
- Первая строка сообщает текущий размер кучи как 202 МБ (206848 КБ) — также используется 42 МБ (43061 КБ).
- Регионы G1 имеют размер 1 МБ, 43 региона отмечены как молодые, а 3 — как выжившие.
- Текущая емкость метапространства составляет около 13,5 МБ (13724 КБ). Из этих 13,5 МБ используется около 12,5 МБ (12983 КБ). Кроме того, у нас может быть до 1 ГБ метапространства (1048576 КБ). Кроме того, 13842 КБ гарантированно доступны для использования виртуальной машиной Java, также известной как выделенная память.
- Последняя строка показывает, какая часть метапространства используется для хранения информации о классе.
Этот вывод может меняться в зависимости от алгоритма GC . Например, если мы запустим одно и то же приложение Quarkus с ZGC через «-XX:+UnlockExperimentalVMOptions -XX:+UseZGC»
:
ZHeap used 28M, capacity 200M, max capacity 1024M
Metaspace used 21031K, capacity 21241K, committed 21504K, reserved 22528K
Как показано выше, мы используем 28 МБ кучи и около 20 МБ метапространства. На момент написания этой статьи Intellij IDEA все еще использует CMS GC со следующей информацией о куче:
par new generation total 613440K, used 114299K
eden space 545344K, 18% used
from space 68096K, 16% used
to space 68096K, 0% used
concurrent mark-sweep generation total 1415616K, used 213479K
Metaspace used 423107K, capacity 439976K, committed 440416K, reserved 1429504K
class space used 55889K, capacity 62488K, committed 62616K, reserved 1048576K
Мы можем заметить классическую природу генерации CMS GC в конфигурации кучи.
3. jstat
В дополнение к jcmd
мы можем использовать jstat
для получения той же информации из запущенных приложений. Например, мы можем использовать jstat -gc
для просмотра статистики кучи:
$ jstat -gc 4309
S0C S1C S0U S1U EC EU OC OU MC
0.0 0.0 0.0 0.0 129024.0 5120.0 75776.0 10134.6 20864.0
MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCTGCT
19946.2 2688.0 2355.0 2 0.007 1 0.020 0 0.000 0.027
Каждый столбец представляет объем памяти или использование определенной области памяти:
- S0C — Вместимость первого места для выживших.
- S1C — Вместимость второго места для выживших.
- S0U — Использованное пространство первого выжившего
- S1U — Использованное пространство второго выжившего
- EC — Емкость пространства Эдема
- ЕС — Используемое пространство из Эдема
- OC — Старая генерирующая мощность
- OU — Используемое пространство от Старого поколения
- MC — Емкость метапространства
- MU — Используемое пространство из Metaspace
- CCSC - Пространственная вместимость сжатого класса
- CCSU — Используемое пространство для сжатых классов
- YGC — Количество второстепенных GC
- YGCT — время, потраченное на второстепенные GC
- FGC — количество полных GC
- FGCT — время, потраченное на полные GC
- CGC — количество одновременных сборщиков мусора
- CGCT — время, потраченное на одновременные сборщики мусора
- GCT — время, потраченное на все GC
Существуют и другие параметры, связанные с памятью, для jstat
, такие как:
- -gccapacity , чтобы
сообщать
о разных емкостях для разных областей памяти . - -gcutil
показывает
только процент использования каждого региона. -gccause
аналогичен-gcutil
, но добавляет причину последнего GC и, возможно, текущих событий GC.
4. Аргументы командной строки
Если мы запускаем приложение Java с параметрами конфигурации кучи (например, -Xms
и -Xmx
), то есть несколько других приемов для поиска указанных значений.
Например, вот как jps
сообщает об этих значениях:
$ jps -lv
4309 quarkus.jar -Xms200m -Xmx1g
При таком подходе мы можем найти только эти статические значения. Таким образом, нет никакого способа узнать, скажем, о текущей выделенной памяти .
В дополнение к jps
несколько других инструментов сообщат о том же. Например, «jcmd <pid> VM.command_line»
также сообщит эти данные:
$ jcmd 4309 VM.command_line
4309:
VM Arguments:
jvm_args: -Xms200m -Xmx1g
java_command: quarkus.jar
java_class_path (initial): quarkus.jar
Launcher Type: SUN_STANDARD
Кроме того, в большинстве систем на основе Unix мы можем использовать ps
из пакета procps
:
$ ps -ef | grep quarkus
... java -Xms200m -Xmx1g -jar quarkus.jar
Наконец, в Linux мы можем использовать виртуальную файловую систему /proc
и ее pid-файлы:
$ cat /proc/4309/cmdline
java -Xms200m -Xmx1g -jar quarkus.jar
Файл cmdline
в каталоге, названном в честь pid Quarkus, содержит запись командной строки для приложения.
5. Вывод
В этом кратком руководстве мы рассмотрели несколько различных способов получения размера кучи работающего Java-приложения.