← Назад к вопросам
Как анализировать Heap Dump в Java?
3.0 Senior🔥 151 комментариев
#JVM и управление памятью
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как анализировать Heap Dump в Java
Heap Dump — это снимок состояния памяти JVM в конкретный момент времени. Его анализ критичен для отладки утечек памяти и оптимизации приложений.
Что такое Heap Dump
Это файл, содержащий:
- Все объекты в памяти JVM
- Значения полей
- Граф ссылок между объектами
- Информацию о классах
- Размер каждого объекта
Когда создавать Heap Dump
Признаки проблемы с памятью:
- OutOfMemoryError
- Приложение медленнеет со временем
- Память растёт и никогда не освобождается
- GC паузы становятся всё дольше
Способ 1: Автоматически при OutOfMemoryError
java -Xmx1024m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/heap_dumps \
-jar application.jar
Результат: автоматически создаёт файл .hprof при OutOfMemoryError.
Способ 2: Программно через JVMTI
import com.sun.management.HotSpotDiagnosticMXBean;
import java.lang.management.ManagementFactory;
public class HeapDumpHelper {
public static void dumpHeap(String filePath) throws Exception {
HotSpotDiagnosticMXBean mbean =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
mbean.dumpHeap(filePath, true);
System.out.println("Heap dump создан: " + filePath);
}
}
Способ 3: jcmd (рекомендуется)
jcmd -l # Показать все Java процессы
jcmd <PID> GC.heap_dump /tmp/heap.hprof # Создать dump
ls -lh /tmp/heap.hprof # Проверить размер
Способ 4: jmap (legacy)
jmap -dump:live,format=b,file=/tmp/heap.hprof <PID>
jmap -heap <PID> # Статистика GC
jmap -histo <PID> # Топ объектов по памяти
Инструменты анализа Heap Dump
1. Eclipse Memory Analyzer Tool (MAT) — ЛУЧШИЙ
Бесплатный, мощный, удобный:
- Leak Suspects Report — автоматически находит утечки
- Dominator Tree — какие объекты держат память
- OQL queries — SQL-подобные запросы к heap
- Path to GC Roots — почему объект не удаляется
2. JProfiler
Коммерческий, очень мощный:
- Live heap анализ без dump
- Профилирование потоков
- CPU profiling
- Интеграция с IDE
3. YourKit Java Profiler
Другой коммерческий вариант:
- Очень удобный UI
- Real-time heap analysis
- Exception tracking
Анализ с помощью MAT: практический пример
public class MemoryLeakApp {
static class ListenerManager {
private List<Listener> listeners = new ArrayList<>();
public void addListener(Listener listener) {
listeners.add(listener);
}
// БЕЗ removeListener!
}
public static void main(String[] args) throws Exception {
ListenerManager manager = new ListenerManager();
for (int i = 0; i < 100_000; i++) {
manager.addListener(new Listener());
}
HotSpotDiagnosticMXBean mbean =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
mbean.dumpHeap("/tmp/leak.hprof", true);
}
}
Анализ в MAT:
- Открыть leak.hprof в MAT
- Нажать "Leak Suspects" → автоматически найдёт ArrayList с 100k Listener объектов
- Нажать "See accumulated objects" → получить список
- Нажать "Path to GC Roots" → увидеть цепь ссылок
- Вывод: нужно вызывать removeListener!
Распространённые утечки памяти
Static Collections
private static List<Resource> resources = new ArrayList<>();
// Исправить: использовать WeakHashMap или явно очищать
Listeners без unsubscribe
eventBus.subscribe(this);
// Забыли unsubscribe в destroy()
@PreDestroy
public void destroy() {
eventBus.unsubscribe(this);
}
Thread Local
ThreadLocal<Resource> local = new ThreadLocal<>();
try {
local.set(resource);
} finally {
local.remove(); // ВАЖНО!
}
Jar/Class Loading
try (URLClassLoader loader = new URLClassLoader(...)) {
// использовать
} // Автоматический close
OQL Queries в MAT
SELECT * FROM java.lang.String s
WHERE toString(s) LIKE ".*password.*"
SELECT * FROM java.util.ArrayList
WHERE size() > 1000
Анализ через jhat
jhat -J-Xmx1024m /tmp/heap.hprof
# Открыть http://localhost:7000
Команда анализа для production
#!/bin/bash
PID=$1
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DUMP_FILE="heap_dump_${TIMESTAMP}.hprof"
jcmd $PID GC.heap_dump "$DUMP_FILE"
gzip "$DUMP_FILE"
scp "${DUMP_FILE}.gz" developer@analysis-server:/data/dumps/
Мониторинг использования памяти
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
long percentage = (usedMemory * 100) / maxMemory;
if (percentage > 80) {
System.gc(); // Подсказка (не гарантирует)
}
Чеклист анализа Heap Dump
- Создать heap dump в момент проблемы
- Открыть в MAT или другом анализаторе
- Посмотреть Leak Suspects Report
- Для каждого подозреваемого:
- Понять, что это за объект
- Проверить Path to GC Roots
- Найти в исходном коде
- Определить, почему не удаляется
- Добавить fix в код
- Создать unit-тест для проверки
- Мониторить память после деплоя
Heap Dump анализ — это важный скилл для senior разработчиков, позволяющий находить и исправлять сложные проблемы с памятью в production.