Питання 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. Що таке витік пам’яті і як його виявити]]
  • [[19. Що станеться при OutOfMemoryError]]
  • [[18. Що таке параметри -Xms та -Xmx]]