Вопрос 24 · Раздел 3

Как получить heap dump?

4. JFR для больших Heap 5. Security — маскируйте PII 6. Осторожно с -all=false (Full GC!)

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Способы получить Heap Dump:

# 1. Автоматически при OOME (обязательно!)
java -XX:+HeapDumpOnOutOfMemoryError -jar app.jar

# 2. Вручную через jcmd
jcmd <PID> GC.heap_dump dump.hprof

# 3. Через VisualVM (GUI)
# → Правый клик на процессе → Heap Dump

Где найти PID:

jps  # Список Java процессов
# или
ps aux | grep java

🟡 Middle Level

jcmd (рекомендуемый способ)

# Современный стандарт
jcmd <PID> GC.heap_dump /tmp/dump.hprof

# С сжатием (Java 11+)
jcmd <PID> GC.heap_dump -gz=1 /tmp/dump.hprof.gz
# → 32 ГБ → 6-10 ГБ

# Только живые объекты (Full GC!)
jcmd <PID> GC.heap_dump -all=false /tmp/live.hprof

Kubernetes

# 1. Вход в под
kubectl exec -it <pod> -- bash

# 2. Снятие дампа
# В контейнерах Java может быть PID 1 (без init-процесса) или иметь
# отдельный PID (с tini/dumb-init или Java 11+ container awareness).
# Проверьте через `jps`.
jcmd 1 GC.heap_dump -gz=1 /tmp/dump.hprof.gz

# 3. Скачивание
kubectl cp <pod>:/tmp/dump.hprof.gz ./dump.hprof.gz

# 4. Очистка
rm /tmp/dump.hprof.gz

Программный способ

// ⚠️ com.sun.management.* — внутренний JDK API (HotSpot-specific).
// Не гарантируется на non-HotSpot JVM (OpenJ9, GraalVM Native Image).
import com.sun.management.HotSpotDiagnosticMXBean;

public void dumpHeap(String path, boolean live) {
    HotSpotDiagnosticMXBean bean = ManagementFactory
        .newPlatformMXBeanProxy(
            ManagementFactory.getPlatformMBeanServer(),
            "com.sun.management:type=HotSpotDiagnostic",
            HotSpotDiagnosticMXBean.class);
    bean.dumpHeap(path, live);
}

🔴 Senior Level

Опасности дампа в production

STW пауза → Liveness Probe fail → под убит!
  
Решение:
  1. Увеличить timeout probes
  2. Использовать JFR вместо дампа
  3. Снимать дамп на реплике

PII и Security

Дамп содержит:
  → Пароли, токены, сессии
  → Персональные данные
  
→ Передавайте только через защищённые каналы
→ RedactHprof для маскировки строк
→ Ограничивайте доступ к файлу

Arthas

# Альтернатива jcmd
curl -L https://arthas.aliyun.com/arthas-boot.jar -o arthas-boot.jar
java -jar arthas-boot.jar

[arthas]$ heapdump /tmp/dump.hprof
→ Сам найдёт PID
→ Удобный CLI

Best Practices

  1. jcmd — официальный способ
  2. -gz=1 (Java 11+) — сжатие
  3. Kubernetes → external volume
  4. JFR для больших Heap
  5. Security — маскируйте PII
  6. Осторожно с -all=false (Full GC!)

Резюме для Senior

  • jcmd > jmap (современный стандарт)
  • Gzip (Java 11+) = экономия
  • Kubernetes → external volume
  • JFR > Dump для > 64 ГБ
  • PII = дамп содержит секреты
  • Arthas = удобный альтернативный способ

🎯 Шпаргалка для интервью

Обязательно знать:

  • jcmd — официальный способ: jcmd <PID> GC.heap_dump /tmp/dump.hprof; сжатие: -gz=1 (Java 11+)
  • Автоматически: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/dumps/ — обязательно в production
  • Kubernetes: вход в под → jcmd 1 GC.heap_dump -gz=1 /tmp/dump.hprof.gzkubectl cp → очистка
  • -all=false (live): только живые объекты; требует Full GC перед дампом → дополнительная STW пауза
  • PII и Security: дамп содержит пароли, токены, сессии; передавайте через защищённые каналы; RedactHprof для маскировки
  • Опасности в production: STW → Liveness Probe fail → под убит; решения: увеличить timeout, использовать JFR, снимать на реплике
  • Программный способ: HotSpotDiagnosticMXBean.dumpHeap() — HotSpot-specific, не работает на OpenJ9/GraalVM Native Image

Частые уточняющие вопросы:

  • Почему -gz=1 важен? — Сжатие на лету: 32 ГБ → 6-10 ГБ; экономия места на диске и времени передачи
  • Что если Java PID 1 в контейнере? — В контейнерах Java может быть PID 1 (без init-процесса); jcmd 1 работает; проверьте через jps
  • Почему программный способ не кроссплатформенный?com.sun.management.HotSpotDiagnosticMXBean — внутренний JDK API; только HotSpot
  • Когда Arthas лучше jcmd? — Arthas находит PID автоматически, удобный интерактивный CLI; хорош когда jcmd недоступен

Красные флаги (НЕ говорить):

  • jmap — лучший способ» — jmap deprecated; используйте jcmd
  • «Live дамп быстрее и безопаснее» — Live дамп требует Full GC → дополнительная STW пауза
  • «Дамп можно хранить в эфемерном хранилище Kubernetes» — эфемерное хранилище забьётся → под не перезапустится

Связанные темы:

  • [[23. Что такое heap dump]]
  • [[22. Какие инструменты помогают анализировать память]]
  • [[21. Что такое memory leak и как его обнаружить]]
  • [[19. Что произойдёт при OutOfMemoryError]]
  • [[18. Что такое параметры -Xms и -Xmx]]