
Heap dump – это бинарный снимок кучи JVM, содержащий все объекты, ссылки и метаданные на момент выгрузки. Такой файл позволяет исследовать утечки памяти, избыточное потребление ресурсов и поведение сборщика мусора. Размер heap dump обычно сопоставим с объемом используемой кучи и может достигать десятков гигабайт.
Получение дампа из запущенного процесса возможно без его остановки. Для этого применяются штатные инструменты JDK: jmap, jcmd, а также удалённые агенты через JMX или Attach API. Важно учитывать влияние процедуры на производительность: во время записи дампа процесс может кратковременно подвиснуть.
Выбор метода зависит от ограничений среды. На серверах без отладки предпочтительнее использование jcmd, так как он минимизирует нагрузку и поддерживает современные версии JVM. В контейнеризированных окружениях удобнее запуск через PID, полученный из docker exec или kubectl exec. Для критичных систем стоит заранее протестировать процедуру на стенде с аналогичными параметрами памяти.
Как снять heap dump из работающего Java процесса

Подготовка: убедитесь, что на хосте установлены инструменты JDK (рекомендуется та же версия JDK, что и JVM процесса). Проверьте свободное место на разделе, куда будет сохраняться дамп: df -h /путь/к/директории. Дамп обычно занимает около объёма используемой Java-кучи; оставьте дополнительно ~10–20% запаса.
Найти PID: используйте jcmd -l или jps -v. Если этих утилит нет, выполните ps aux | grep java и подтвердите процесс по аргументам командной строки.
Рекомендуемая команда (предпочтительна для JDK 7u+ и OpenJDK 8+): jcmd <PID> GC.heap_dump /путь/имя_дампа.hprof. Пример: jcmd 12345 GC.heap_dump /var/tmp/heap-20250911.hprof.
Если jcmd недоступен – альтернативы: jmap -dump:live,format=b,file=/путь/имя_дампа.hprof <PID> (опция live сохраняет только живые объекты и часто уменьшает размер). Учтите: jmap в редких случаях может привести к аварийному завершению старых JVM – заранее тестируйте на стейджинге.
Права и пользователь: выполнять команды должен тот же пользователь, что и JVM, или root. На контейнерах используйте docker exec -it контейнер — jcmd <PID> … или внутри Pod: kubectl exec -it pod — jcmd <PID> GC.heap_dump /tmp/heap.hprof. В контейнере PID процесса часто равен 1 – проверьте jcmd -l.
Где лучше сохранять дамп: на локальном диске с высокой скоростью записи (SSD), а не в сетевом NFS, если возможна блокировка записи. Если диск мал, пишите во временную директорию с достаточным пространством и затем переносите файл: scp или rsync.
Контролировать размер и прогресс: во время записи проверяйте занимаемое пространство: watch -n 2 ls -lh /путь/имя_дампа.hprof. После завершения сжмите файл: gzip -9 /путь/имя_дампа.hprof.
Автоматический дамп при OOME: добавьте в опции JVM: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/путь/. Это создаст дамп при выбросе OutOfMemoryError.
Рекомендации безопасности и стабильности: снимайте дампы в не пиковое время; создание дампа вызывает остановку приложения на время записи – продолжительность зависит от размера кучи и производительности диска. Тестируйте процедуру на стейджинге, особенно для JVM с нестандартными GC или старыми версиями.
Открытие дампа: используйте Eclipse MAT или VisualVM; для уменьшения размера предпочтительны дампы с live. Если дамп повреждён, проверьте целостность файловой системы и логи JVM (hs_err, stderr).
Короткая контрольная таблица действий: 1) проверить свободное место; 2) найти PID (jcmd -l); 3) выполнить jcmd PID GC.heap_dump /path/name.hprof (или jmap -dump:live,…); 4) проверить файл и сжать; 5) перенести в анализ-окружение.
Определение PID нужного Java процесса

Если в системе используется несколько Java-процессов с одинаковыми jar-файлами, следует уточнять PID через ps. Например, команда ps -ef | grep java позволит увидеть аргументы запуска JVM. По ним можно однозначно определить нужное приложение.
На Windows аналогичную задачу выполняет tasklist. Вызов tasklist /FI «IMAGENAME eq java.exe» отобразит все процессы Java с указанием PID. При необходимости уточнить аргументы запуска удобно применять wmic process, например: wmic process where «name=’java.exe'» get ProcessId,CommandLine.
После получения PID убедитесь, что процесс принадлежит целевому приложению. Ошибка в выборе приведёт к созданию дампа не того экземпляра JVM, что затруднит анализ.
Использование jmap для снятия heap dump

Утилита jmap входит в состав JDK и позволяет снимать дампы памяти напрямую из работающего процесса JVM. Для выполнения операции необходим PID целевого процесса.
- Определите PID с помощью команды
jps -lили стандартных средств ОС (ps,tasklist). - Выполните команду:
jmap -dump:live,format=b,file=/path/to/heap.hprof PID
Ключи:
live– сохраняет только объекты, доступные из корней, что уменьшает размер файла;format=b– бинарный формат, совместимый с анализаторами (VisualVM, Eclipse MAT);file– путь для сохранения дампа.
Примеры:
jmap -dump:live,format=b,file=/tmp/app_heap.hprof 12345jmap -dump:format=b,file=/tmp/full_heap.hprof 12345– включает все объекты, в том числе недостижимые.
Рекомендации:
- Запускайте на той же версии JDK, что и процесс, иначе возможны ошибки.
- На больших приложениях используйте опцию
live, чтобы сократить нагрузку и время генерации. - Убедитесь в наличии достаточного свободного места, так как размер файла может соответствовать объёму кучи.
- При невозможности остановки приложения снимайте дамп в часы минимальной нагрузки.
Снятие heap dump с помощью jcmd
Описание команды: для создания heap dump используйте команду jcmd <pid> GC.heap_dump <путь/имя.hprof>. jcmd входит в комплект JDK и выполняется от пользователя, под которым запущен JVM; при необходимости применяйте sudo -u или запускайте от root.
Нахождение PID: jcmd -l или jps -l или ps -ef | grep java. Пример: jcmd 12345 GC.heap_dump /tmp/heapdump-2025-09-11.hprof.
Рекомендованная последовательность для минимального размера дампа: 1) запуск быстрых сборок мусора: jcmd <pid> GC.run; 2) затем создание дампа: jcmd <pid> GC.heap_dump /путь/файл.hprof. Это снижает количество неживых объектов в файле.
Требования по свободному месту: убедитесь, что на целевом разделе свободно как минимум ≈ используемый объём heap × 1.2 (резерв на метаданные и накладные данные). Проверка: pmap <pid> | grep total или jcmd <pid> GC.heap_info для оценки размеров и df -h /target/path для диска.
Где безопасно писать: избегайте сетевых томов (NFS, CIFS) для больших дампов – предпочитайте локальные SSD/HDD. При недостатке места снимайте дамп в локальный временный каталог и затем копируйте/сжимайте: gzip -9 /tmp/heapdump.hprof.
Влияние на приложение: операция блокирует поток выполнения JVM на время создания дампа; длительность зависит от live-heap (для heap ≈ 16 ГБ пауза может составить десятки секунд – несколько минут на медленных дисках). Планируйте выполнение в окне низкой нагрузки.
Права и безопасность: файл содержит полные ссылки на объекты – храните его в безопасном месте, удаляйте после анализа. Если JVM запущена под другим юзером, используйте sudo -u <user> jcmd … или выполните команду от владельца процесса.
Проверка результата: после выполнения команда вернёт подтверждение и путь; дополнительно проверьте существование и размер: ls -lh /путь/файл.hprof. Ожидаемый размер ≈ используемая heap + 10–20%.
Альтернативные варианты при нехватке времени/пространства: 1) соберите class histogram для быстрой диагностики: jcmd <pid> GC.class_histogram; 2) используйте флаги JVM для автоматического дампа при OOM: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path.
Примеры: создание дампа и сжатие:
jcmd 12345 GC.runjcmd 12345 GC.heap_dump /tmp/heapdump-2025-09-11.hprofgzip -9 /tmp/heapdump-2025-09-11.hprof
Частые ошибки: недостаток прав, недостаточно места, запись в медленный сетевой том – проверяйте сообщения jcmd и системные логи, при ошибке повторяйте запись в локальный каталог с контролем свободного места.
Получение heap dump при помощи VisualVM

Запустите VisualVM и убедитесь, что целевой процесс Java отображается в списке «Local» или «Remote». Если процесс не виден, проверьте наличие JMX-коннектора или корректность настроек удалённого подключения.
Выберите нужное приложение в левой панели и откройте вкладку «Monitor», чтобы убедиться, что соединение установлено и данные о памяти обновляются в реальном времени.
Чтобы проанализировать полученный дамп, откройте его в VisualVM двойным кликом: инструмент загрузит граф объектов, статистику классов и список удерживающих ссылок. При необходимости можно экспортировать файл с расширением .hprof и открыть его в других анализаторах, например Eclipse MAT.
Если heap dump требуется на сервере без графического окружения, можно подключиться удалённо: настройте запуск JVM с параметрами -Dcom.sun.management.jmxremote и используйте VisualVM на рабочей станции для инициирования дампа.
Снятие дампа через JConsole
JConsole позволяет оперативно получить heap dump из работающего Java-процесса без перезапуска приложения. Для этого необходимо выполнить следующие шаги:
- Запустите JConsole с правами пользователя, который владеет Java-процессом:
- Команда:
jconsole - Если процесс запущен на удалённой машине, используйте подключение через JMX:
service:jmx:rmi:///jndi/rmi://host:port/jmxrmi - Выберите нужный процесс из списка локальных процессов или подключитесь к удалённому процессу через JMX.
- Перейдите на вкладку MBeans и раскройте дерево:
java.lang → Memory. - Найдите операцию dumpHeap в списке доступных методов.
- Вызовите
dumpHeapс параметрами: file– полный путь к файлу дампа, например/tmp/heapdump.hproflive– true для включения только живых объектов, false для полного дампа- Подтвердите выполнение. JConsole создаст файл дампа и укажет путь в интерфейсе.
- После снятия дампа рекомендуется проверить размер файла и доступность дискового пространства, особенно для крупных приложений.
Рекомендации по использованию:
- Для долгоживущих приложений лучше ставить
live=true, чтобы снизить размер дампа. - Для анализа проблем с OutOfMemoryError предпочтителен полный дамп (
live=false). - Если JConsole подключается к удалённому процессу, убедитесь, что JMX-порт защищён и доступен только доверенным клиентам.
- Создаваемый дамп можно открыть в
VisualVMилиEclipse MATдля анализа распределения памяти.
Автоматическое создание heap dump при OutOfMemoryError
Для автоматического получения heap dump при возникновении OutOfMemoryError в JVM используется параметр -XX:+HeapDumpOnOutOfMemoryError. Этот флаг позволяет JVM сгенерировать дамп памяти в момент ошибки без вмешательства администратора.
Дополнительно можно указать путь и имя файла для heap dump с помощью -XX:HeapDumpPath=/путь/к/файлу/heapdump.hprof. Без этого параметра файл создаётся в рабочем каталоге процесса или в каталоге с правами на запись JVM.
Пример запуска Java-приложения с автоматическим дампом:
| Параметр | Описание |
|---|---|
| -XX:+HeapDumpOnOutOfMemoryError | Включает автоматическое создание heap dump при OutOfMemoryError |
| -XX:HeapDumpPath=/var/logs/heapdumps/ | Определяет путь для сохранения дампа памяти |
| -Xmx2g | Ограничивает размер кучи до 2 ГБ (рекомендуется явно задавать максимальный размер) |
Heap dump может быть значительного размера. Рекомендуется убедиться, что на диске достаточно свободного места и каталог доступен для записи JVM. Для приложений с высокой нагрузкой лучше назначить отдельный каталог с мониторингом свободного пространства.
Файлы heap dump удобно анализировать с помощью инструментов jvisualvm, Eclipse MAT или jhat. Для регулярного мониторинга можно настроить cron-задачу на перенос или архивирование старых дампов, чтобы не перегружать файловую систему.
Анализ и хранение полученных heap dump файлов
После снятия heap dump файла важно организовать его хранение и анализ. Рекомендуется сохранять файлы с указанием даты, времени и PID процесса для удобной идентификации. Например: heapdump_2025-09-11_1430_pid1234.hprof.
Для анализа можно использовать инструменты Eclipse MAT (Memory Analyzer Tool), VisualVM или JProfiler. MAT позволяет строить отчеты о retained size, dominator tree и искать утечки памяти через Leak Suspects Report. VisualVM подходит для быстрого просмотра классов с наибольшим потреблением памяти и мониторинга изменений между сессиями.
При работе с большими heap dump файлами (>2–3 ГБ) рекомендуется открывать их на серверах с объемом памяти не менее 1.5–2 раза больше размера файла. Для MAT можно использовать ключ -Xmx при запуске: mat -Xmx8g для файла 4 ГБ.
Рекомендуется хранить файлы в сжатом виде (gzip или zip), так как hprof файлы часто занимают несколько гигабайт. Для долгосрочного хранения лучше использовать отдельный NAS или облачное хранилище с версионностью, чтобы можно было отслеживать динамику использования памяти в разных версиях приложения.
Для автоматизации анализа и хранения можно настроить скрипты, которые при снятии heap dump будут: копировать файл в архив, переименовывать по шаблону, запускать MAT для генерации отчета в формате HTML или CSV и уведомлять команду через почту или Slack.
При совместной работе над проектом важно фиксировать контекст процесса: версия JDK, параметры JVM, загруженные модули и описание ситуации, при которой был снят heap dump. Это облегчает повторный анализ и сравнение между разными сессиями.
Вопрос-ответ:
Какие инструменты можно использовать для снятия heap dump с работающего Java процесса?
Существует несколько стандартных инструментов для снятия heap dump. Среди них — jcmd, jmap и VisualVM. Jcmd позволяет выполнять команды для конкретного Java процесса по его PID, включая снятие heap dump. Jmap работает аналогично и поддерживает создание дампа напрямую в файл. VisualVM предоставляет графический интерфейс, где можно подключиться к процессу и сохранить состояние памяти в виде heap dump.
Можно ли снять heap dump без перезапуска приложения?
Да, heap dump можно получить с работающего процесса без остановки приложения. Инструменты вроде jcmd и jmap позволяют создать дамп «на лету». Однако следует учитывать, что в момент создания heap dump приложение может временно замедлиться, так как инструмент блокирует сборщик мусора на время записи состояния памяти в файл.
Какой формат файла создается при снятии heap dump?
Heap dump обычно сохраняется в формате HPROF, который поддерживается большинством анализаторов памяти для Java. Этот формат содержит информацию о всех объектах, их типах, размерах и ссылках между ними. Файл HPROF можно открыть в таких инструментах, как Eclipse Memory Analyzer, VisualVM или YourKit для дальнейшего анализа утечек памяти и профилирования.
Сколько времени занимает создание heap dump для большого приложения?
Время создания heap dump зависит от размера используемой памяти и активности приложения. Для процессов с небольшим объемом памяти это может быть несколько секунд, а для больших сервисов с несколькими гигабайтами занятой памяти процесс может занять десятки секунд или даже минуты. Важно планировать снятие дампа в периоды минимальной нагрузки, чтобы не повлиять на производительность сервиса.
Какие проблемы могут возникнуть при снятии heap dump на продакшн сервере?
На продакшн сервере при снятии heap dump возможны следующие проблемы: временное замедление работы приложения, увеличение нагрузки на дисковую подсистему, и в случае очень больших процессов может закончиться нехваткой памяти или дискового пространства. Рекомендуется заранее проверять доступное место на диске и учитывать нагрузку на JVM, чтобы не нарушить работу сервиса.
Можно ли снять heap dump с работающего Java процесса без перезапуска приложения?
Да, это возможно. Для этого обычно используют встроенные инструменты Java, такие как jcmd или jmap. Например, с помощью команды jcmd можно создать дамп памяти текущего процесса. Важно убедиться, что у процесса достаточно прав для снятия дампа, и что это не приведёт к падению приложения из-за нехватки памяти во время записи.
Как определить, какой инструмент выбрать для снятия heap dump: jmap или jcmd?
Выбор зависит от версии Java и конкретной задачи. jmap доступен во всех версиях Java и позволяет быстро создать дамп, но при этом может заблокировать работу приложения на время записи. jcmd появился позже и даёт больше возможностей: можно не только снять heap dump, но и запросить информацию о потоках, сборке мусора и других внутренних состояниях JVM. Если важно минимизировать влияние на приложение, обычно рекомендуют jcmd.
