JVM в проде — jcmd, дамп памяти и JFR
JVM в проде — jcmd, дамп памяти и JFR
Теория GC и потоков — в JVM, память и потоки. Здесь — практика: какие команды ввести, когда приложение тормозит, «ест» память или упало с OutOfMemoryError.
Инструменты входят в JDK (каталог bin рядом с java), не в урезанную JRE: jcmd, jmap, jfr.
Словарь перед командами
| Термин | Объяснение |
|---|---|
| JVM | Процесс, в котором крутится ваш .jar (Spring Boot, Tomcat внутри) |
| PID | Номер процесса в ОС; подставляете вместо <pid> в командах |
| Heap (куча) | Память для объектов (new, коллекции); OOM Java heap space — про неё |
| Metaspace | Память под метаданные классов; отдельный OOM Metaspace |
| Heap dump | Снимок всех объектов в куче в файл .hprof для анализа |
| Thread dump | Снимок стеков всех потоков в момент времени — ищут deadlock и «горячий» код |
| JFR | Java Flight Recorder — короткая запись профиля: CPU, GC, аллокации |
| GC | Сборщик мусора освобождает объекты без ссылок |
Когда что делать (дерево решений):
Приложение «висит» или CPU 100% → Thread.print (jcmd)
OutOfMemoryError / память растёт → heap dump + Eclipse MAT / IDEA
Нужно «где тормозит метод» → JFR 60 сек + JDK Mission Control
Когда открывать эту статью
| Симптом | Первый шаг |
|---|---|
| «Висит», CPU 100% | jcmd <pid> Thread.print |
OutOfMemoryError: Java heap space | heap dump + анализ |
| Нужно понять, куда ушло время | короткая запись JFR |
1. Найти PID процесса
Linux / macOS:
jcmd
# или
ps aux | grep java
Windows (PowerShell):
jcmd
# или диспетчер задач → подробности → java.exe
Запомните число PID — подставляйте вместо <pid> ниже. Если процессов Java несколько, смотрите колонку с main-классом или аргументами (com.example.demo.DemoApplication).
Проверка JDK: java -version и jcmd -h должны работать из той же установки, которой запущено приложение.
2. Снимок потоков (зависания, высокий CPU)
jcmd <pid> Thread.print > threads.txt
Откройте threads.txt: ищите повторяющийся стек в состоянии RUNNABLE — часто там цикл или блокировка.
Разбор файла threads.txt:
| Что видите | Как читать |
|---|---|
"main" #1 prio=5 os_prio=0 tid=... | Имя потока и номер |
java.lang.Thread.State: RUNNABLE | Поток выполняется или ждёт CPU |
BLOCKED / WAITING | Ждёт lock или wait() |
at com.example.service.Foo.bar(Foo.java:42) | Стек: сверху вниз — от текущего кадра к main |
Один и тот же at ... десятки раз в RUNNABLE | Частый признак бесконечного цикла или горячего метода |
Deadlock: в конце дампа JVM иногда печатает Found one Java-level deadlock — два потока держат lock друг друга.
3. Heap dump (утечки памяти, OOM)
jcmd <pid> GC.heap_dump heap.hprof
Альтернатива (устаревающая, но встречается):
jmap -dump:live,format=b,file=heap.hprof <pid>
Файл heap.hprof откройте в Eclipse MAT, VisualVM или IntelliJ IDEA (Analyze Heap Dump).
На что смотреть в анализаторе:
- Dominator tree — кто держит больше всего памяти;
- Leak Suspects — эвристики утечек;
- сравнение двух дампов «до/после» нагрузки.
:::tip OOM в логах
Запустите JVM с -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumps — дамп появится автоматически при падении.
:::
4. Краткая запись JFR (профилирование)
Java Flight Recorder — встроенный профайлер Oracle JDK / Temurin 11+.
Запись 60 секунд:
jcmd <pid> JFR.start name=debug settings=profile duration=60s filename=recording.jfr
# подождать минуту
jcmd <pid> JFR.dump name=debug filename=recording.jfr
jcmd <pid> JFR.stop name=debug
Откройте recording.jfr в JDK Mission Control (JMC) или в IDEA (Analyze JFR Snapshot).
Разбор: в JMC смотрите Method Profiling, GC, Memory — где CPU и аллокации.
5. Минимальный чек-лист инцидента
- Зафиксировать время и версию (
java -version). jcmd <pid> VM.flags— флаги JVM.jcmd <pid> GC.heap_info— размер кучи.Thread.printпри подозрении на deadlock/CPU.- Heap dump или JFR — по типу проблемы.
- Перезапуск только после сбора артефактов (если политика позволяет).
Подробнее о флагах и GC — 23.md, справочник — 3.md.
Пример — учебная утечка
import java.util.ArrayList;
import java.util.List;
public class LeakDemo {
static final List<byte[]> LEAK = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
while (true) {
LEAK.add(new byte[1024 * 1024]); // 1 MiB
Thread.sleep(100);
}
}
}
Запуск с дампом при OOM:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=. LeakDemo
В MAT список byte[] и статическая LEAK будут доминировать — хорошая тренировка чтения дампа.
Частые ошибки
| Ошибка | Что делать |
|---|---|
jcmd не найден | В PATH должен быть каталог bin JDK, не JRE |
| Отказ в доступе к PID | Права пользователя / sudo (осторожно в проде) |
Огромный .hprof | Дамп на диск с местом; live уменьшает размер |
| Путать heap и metaspace | OOM бывает разный — читайте текст исключения |
Что попробовать
- Снять
Thread.printдля своего Spring Boot под нагрузкойabилиcurlв цикле. - Включить
HeapDumpOnOutOfMemoryErrorв dev-профиле. - Вернуться к 23.md и сопоставить GC-логи с JFR.
Дальше
JVM, память и потоки · Отладка в IDEA · Testcontainers
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Основы Java - устройство JDK/JVM, модель компиляции и базовые принципы платформонезависимого выполнения. Java — это объектно-ориентированный язык программирования общего назначения, который работает на принципах «напиши один раз, запускай в любом месте». Набор советов, правил, принципов и обычаев в разработке на этом языке. История Java — от проекта Green и Oak до OpenJDK, LTS-релизов и современной платформы (модули, records, виртуальные потоки). Библиотеки, фреймворки, инструменты сборки, тестирования, развёртывания и мониторинга. Что такое пакет и пакетная структура, как собираются проекты на Java. Справочник-шпаргалка по конфигурациям в Java — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс — раздел. Гайд по установке и настройке с написанием первой программы и её запуском. Практические примеры — консольные утилиты, композиция классов в мини-игре и первое Swing-приложение. Точки останова, пошаговое выполнение, панели Variables и Call Stack — практика отладки в IntelliJ IDEA. Кавычки, точки, запятые, скобки и прочие знаки препинания. Это полный справочник всех ключевых слов языка Java, включая основные, контекстные и зарезервированные слова.Основы языка Java
Что требуется знать перед началом изучения языка программирования Java
Рекомендации по разработке на Java
История языка Java
Экосистема Java-приложений
Структура и сборки Java-проектов
Справочник по конфигурациям в Java
Первая программа на Java
Простые приложения на Java
Отладка Java-кода в IDE
Синтаксис и пунктуация в Java
Ключевые слова в Java