← Назад к вопросам

Как сделать дамп хипа (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:

  1. Открой chrome://inspect
  2. Найди процесс в списке
  3. Нажми "inspect"
  4. Перейди на вкладку "Memory"
  5. Нажми "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

  1. Открой Chrome DevTools → Memory вкладка
  2. Drag & drop файл .heapsnapshot
  3. Выбери инструмент анализа:
    • Chart - визуализация распределения памяти
    • Table - таблица всех объектов
    • Dominators - объекты, удерживающие большую часть памяти

Поиск утечек памяти

  1. Сравни два снимка - создай dump до и после проблемного сценария
  2. Загрузи оба в DevTools
  3. На вкладке "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);

В этом примере:

  1. Каждый запрос с новым id добавляет объект в кэш
  2. Объекты никогда не удаляются
  3. Память растёт бесконечно

Диагностика шагами

# 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.

Как сделать дамп хипа (heap dump) процесса Node.js и что с ним дальше делать? | PrepBro