← Назад к вопросам
Как сделать дамп хипа (heap dump) процесса Node.js и что с ним дальше делать?
3.0 Senior🔥 101 комментариев
#DevOps и инфраструктура#Node.js и JavaScript
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Дамп хипа в Node.js
Heap dump (снимок памяти) - это критический инструмент для диагностики утечек памяти и анализа использования памяти в Node.js приложениях. Это снимок всех объектов, находящихся в памяти JavaScript в определённый момент времени.
Зачем нужен heap dump
- Обнаружение утечек памяти - найти объекты, которые удерживаются в памяти
- Анализ использования памяти - понять, какие объекты занимают больше всего памяти
- Отладка production - исследовать проблемы без перезагрузки приложения
- Оптимизация производительности - выявить неэффективные структуры данных
Способ 1: Встроенный V8 инструмент (v8)
const v8 = require("v8");
const fs = require("fs");
const path = require("path");
// Создать и сохранить heap dump
const heapdump = v8.writeHeapSnapshot();
console.log(`Heap snapshot written to ${heapdump}`);
// Или с кастомным путём
const snapshot = v8.writeHeapSnapshot(
path.join(__dirname, `heap-${Date.now()}.heapsnapshot`)
);
Способ 2: Signal обработка (SIGUSR2)
Обработай сигнал для создания дампа на лету:
const v8 = require("v8");
const fs = require("fs");
const path = require("path");
let dumpIndex = 0;
process.on("SIGUSR2", () => {
const filename = path.join(
process.cwd(),
`heap-dump-${Date.now()}-${dumpIndex++}.heapsnapshot`
);
console.log(`Creating heap dump at ${filename}`);
const snapshot = v8.writeHeapSnapshot(filename);
console.log(`Heap dump written: ${snapshot}`);
});
console.log(`Process PID: ${process.pid}`);
console.log("Send SIGUSR2 signal to trigger heap dump");
// Запуск: kill -SIGUSR2 <PID>
Использование из shell:
# Отправить сигнал процессу
kill -SIGUSR2 12345
# Или через Node.js
process.kill(12345, "SIGUSR2");
Способ 3: Node Inspector (встроенный)
Node.js имеет встроенный инспектор для удалённой отладки:
# Запуск с инспектором
node --inspect app.js
# или
node --inspect-brk app.js # Останавливает выполнение при старте
# Вывод:
# Debugger listening on ws://127.0.0.1:9229/...
Потом откроешь в Chrome DevTools:
- Открой
chrome://inspect - Найди процесс в списке
- Нажми "inspect"
- Перейди на вкладку "Memory"
- Нажми "Take heap snapshot"
Способ 4: Clinic.js (рекомендуется)
Профессиональный инструмент для анализа:
npm install -g clinic
# Запусти приложение с clinic
clinic doctor -- node app.js
# или для heap анализа
clinic heap -- node app.js
# Clinic создаст HTML отчёт
Способ 5: Стороннее хранилище (облако)
Для production приложений:
const v8 = require("v8");
const aws = require("aws-sdk");
const fs = require("fs");
const path = require("path");
const s3 = new aws.S3();
async function uploadHeapDump() {
const filename = `heap-dump-${Date.now()}.heapsnapshot`;
const filepath = path.join("/tmp", filename);
// Создать dump
v8.writeHeapSnapshot(filepath);
// Загрузить в S3
const fileContent = fs.readFileSync(filepath);
await s3.putObject({
Bucket: "my-heap-dumps",
Key: filename,
Body: fileContent
}).promise();
// Удалить локальный файл
fs.unlinkSync(filepath);
console.log(`Uploaded to S3: ${filename}`);
}
process.on("SIGUSR2", uploadHeapDump);
Анализ полученного dump
Использование Chrome DevTools
- Открой Chrome DevTools → Memory вкладка
- Drag & drop файл
.heapsnapshot - Выбери инструмент анализа:
- Chart - визуализация распределения памяти
- Table - таблица всех объектов
- Dominators - объекты, удерживающие большую часть памяти
Поиск утечек памяти
- Сравни два снимка - создай dump до и после проблемного сценария
- Загрузи оба в DevTools
- На вкладке "Comparison" сравни:
- какие объекты были добавлены
- какие объекты выросли в количестве
Анализ через CLI (node-inspect-heapdump)
npm install -g node-inspect-heapdump
# Анализ
heap-analysis heap-dump-123.heapsnapshot
Практический пример: Обнаружение утечки
const v8 = require("v8");
const express = require("express");
const app = express();
// ❌ Утечка: глобальный кэш без лимита
const cache = {};
app.get("/data/:id", (req, res) => {
const { id } = req.params;
if (!cache[id]) {
// Кэшируем объект без удаления
cache[id] = { id, data: new Array(1000000).fill("x") };
}
res.json(cache[id]);
});
// Endpoint для создания dump
app.get("/debug/heapdump", (req, res) => {
const filename = `heap-${Date.now()}.heapsnapshot`;
v8.writeHeapSnapshot(filename);
res.json({ file: filename });
});
app.listen(3000);
В этом примере:
- Каждый запрос с новым
idдобавляет объект в кэш - Объекты никогда не удаляются
- Память растёт бесконечно
Диагностика шагами
# 1. Запусти приложение
node app.js &
# 2. Создай нагрузку (запроси с разными id)
for i in {1..1000}; do curl http://localhost:3000/data/$i; done
# 3. Создай heap dump
kill -SIGUSR2 $(pgrep -f "node app.js")
# 4. Загрузи файл в Chrome DevTools
# chrome://inspect → открой snapshot
# 5. На вкладке "Dominators" найди большие объекты
# 6. Проанализируй: какой объект удерживает память
Best Practices
- Регулярное мониторирование - используй APM инструменты (DataDog, New Relic)
- Ограничивай размер кэшей - используй LRU кэш или с TTL
- Слушай процесс-сигналы - SIGUSR2 для захвата dumps в production
- Автоматизируй анализ - напиши скрипт для загрузки dumps в облако
- Версионируй dumps - сохраняй с timestamp и версией приложения
- Тестируй утечки - в unit тестах проверяй, что объекты удаляются
Heap dumps - мощный инструмент, но их анализ требует понимания всей архитектуры приложения. Лучше всего использовать их в комбинации с профилированием CPU и мониторингом памяти в production.