Питання 22 · Розділ 3

Які інструменти допомагають аналізувати пам'ять?

4. Обережно з дампом → STW пауза 5. NMT для Native Memory 6. gceasy.io для аналізу GC логів 7. Arthas для складних оточень

Мовні версії: English Russian Ukrainian

🟢 Junior Level

Інструменти для аналізу пам’яті:

Інструмент Для чого Коли
Eclipse MAT Аналіз дампів Після OOME
VisualVM Моніторинг Розробка
jcmd Швидка перевірка Production
JProfiler Профілювання Розробка

Найважливіший: Eclipse MAT (безкоштовний)

  • Відкриває дамп хіпу
  • Показує, які об’єкти займають найбільше пам’яті
  • Знаходить витоки

🟡 Middle Level

jcmd (утиліта командного рядка)

jcmd <pid> GC.class_histogram   # Список класів
jcmd <pid> GC.heap_dump dump.hprof  # Зняти дамп
jcmd <pid> VM.native_memory summary  # Native Memory

Eclipse MAT

Ключові функції:
  → Dominator Tree (хто тримає найбільше пам'яті)
  → Path to GC Roots (ланцюжок посилань до кореня)
  → OQL (запити до дампу)
  → Leak Suspects Report (автоматичний аналіз)

JFR і JMC

Java Flight Recorder (вбудований у JVM):
  → Overhead < 1%
  → Можна тримати увімкненим у production

JDK Mission Control (GUI):
  → Візуалізація JFR записів
  → OldObjectSample → витоки без дампа

Комерційні інструменти

Інструмент Плюси Мінуси
JProfiler Live profiling Платний
YourKit Allocation tracking Платний
gceasy.io Аналіз GC логів Хмарний

🔴 Senior Level

Небезпека зняття дампа

Heap Dump = Stop-The-World!
  → 32 ГБ Heap на HDD → 30-60 секунд пауза
  → 32 ГБ Heap на SSD → 5-15 секунд

У Kubernetes:
  → Liveness Probe timeout → под убитий!

Рішення для великих Heap:
  → JFR OldObjectSample (без STW)
  → class_histogram (пауза < 1 сек)

OQL приклади

-- Знайти всі HashMap з > 1000 елементів
SELECT map FROM java.util.HashMap map
WHERE map.size > 1000

-- Знайти дублікати рядків
SELECT toString(s.value) as val, count(*) as cnt
FROM java.lang.String s
GROUP BY toString(s.value)
HAVING count(*) > 100

-- Знайти витоки ThreadLocal
SELECT tl, tl.referents.@length as size
FROM java.lang.ThreadLocal tl
WHERE tl.referents.@length > 100

Arthas (Alibaba)

# Інтерактивна діагностика на сервері
java -jar arthas-boot.jar

[arthas]$ dashboard     # Огляд Heap/Native/Metaspace
[arthas]$ heapdump      # Зняти дамп
[arthas]$ vmtool        # Інспекція об'єктів
[arthas]$ memory        # Деталі пам'яті

NMT (Native Memory Tracking)

-XX:NativeMemoryTracking=detail

jcmd <pid> VM.native_memory detail

# Покаже:
# Java Heap, Class, Thread, Code, GC
# Compiler, Internal, Symbol, Arena Chunk
# → Знайти витоки поза Heap

Best Practices

  1. jcmd > jmap (сучасний стандарт)
  2. JFR для production моніторингу
  3. MAT для аналізу дампів
  4. Обережно з дампом → STW пауза
  5. NMT для Native Memory
  6. gceasy.io для аналізу GC логів
  7. Arthas для складних оточень

Резюме для Senior

  • jcmd = сучасний стандарт CLI
  • MAT = Dominator Tree + Path to GC Roots
  • JFR = < 1% overhead, production-safe
  • NMT = Native Memory Tracking
  • Дамп = STW (усі потоки зупиняються). JVM має заморозити граф об’єктів у консистентному стані: жодних алокацій, deallocations або змін посилань під час дампа. На великих Heap дамп може зайняти 10-60 секунд.
  • OQL = SQL для дампів
  • Arthas = інтерактивна діагностика

🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • Eclipse MAT — аналіз дампів: Dominator Tree, Path to GC Roots, OQL, Leak Suspects Report (безкоштовний)
  • jcmd — сучасний стандарт CLI: GC.class_histogram, GC.heap_dump, VM.native_memory
  • JFR + JMC — production моніторинг, < 1% overhead; OldObjectSample → витоки без дампа
  • NMT (-XX:NativeMemoryTracking=detail): Native Memory Tracking — показує Java Heap, Class, Thread, Code, GC, Internal
  • Дамп = STW: на 32 ГБ HDD → 30-60 секунд; у Kubernetes Liveness Probe timeout → под убитий
  • OQL — SQL-подібні запити до дампу: знайти великі HashMap, дублікати рядків, витоки ThreadLocal
  • Arthas (Alibaba): інтерактивна діагностика на сервері — dashboard, heapdump, vmtool, memory

Часті уточнюючі запитання:

  • Чому jcmd кращий за jmap? — jmap deprecated; jcmd — сучасний стандарт, використовує JVM Attach API, більше команд
  • Коли JFR кращий за дамп? — Heap > 64 ГБ: дамп занадто великий, довго знімати/аналізувати; JFR < 1% overhead, без STW
  • Що показує NMT, чого не видно у Heap Dump? — Native Memory: Code Cache, Thread Stacks, GC structures, Internal — все поза Heap
  • Чому дамп вимагає STW? — JVM має заморозити граф у консистентному стані: жодних алокацій/deallocations під час дампа

Червоні прапорці (НЕ говорити):

  • «Знімаю дамп у production без попередження» — STW 30-60 секунд; у Kubernetes под буде убитий
  • «jmap — найкращий інструмент» — jmap deprecated; використовуйте jcmd
  • «Heap Dump показує всю пам’ять JVM» — Heap Dump тільки On-Heap; Native Memory потребує NMT

Пов’язані теми:

  • [[21. Що таке витік пам’яті і як його виявити]]
  • [[23. Що таке heap dump]]
  • [[24. Як отримати heap dump]]
  • [[19. Що станеться при OutOfMemoryError]]
  • [[18. Що таке параметри -Xms та -Xmx]]