Гид по технологиям

Исправление ошибки «JavaScript heap out of memory» в Node.js

7 min read Node.js Обновлено 05 Jan 2026
Исправление JavaScript heap out of memory в Node.js
Исправление JavaScript heap out of memory в Node.js

Внутренности настольного корпуса компьютера с несколькими жёсткими дисками

Ошибка «JavaScript heap out of memory» часто появляется при запуске крупных Node.js-проектов — на Windows, macOS и Linux. Её причинами могут быть как реальные утечки памяти в коде, так и простое превышение дефолтного лимита памяти, установленного движком V8. В этой статье мы разберём, что такое куча (heap), почему возникает ошибка, как быстро её исправить на разных ОС и как правильно диагностировать и устранить корневую причину.

Что такое heap-память

Куча (heap) — область динамически выделяемой памяти, используемая для объектов и структур данных во время выполнения программы. Короткое определение: heap — это место, куда среда выполнения помещает объекты при создании во время выполнения.

Алгоритмы сборки мусора (garbage collectors) контролируют освобождение неиспользуемых объектов, но сами по себе они не увеличивают лимит выделенной виртуальной памяти процесса. Лимит кучи для процесса Node.js определяется движком V8 и может быть изменён флагом –max-old-space-size или через переменную окружения NODE_OPTIONS.

Силуэт черепа, составленный из символов и кода

Почему возникает ошибка

Основные причины возникновения “JavaScript heap out of memory”:

  • Дефолтный лимит V8 слишком мал для объёма данных, обрабатываемых приложением.
  • Утечка памяти: объекты удерживаются в памяти дольше, чем нужно (замыкания, глобальные кэши, незакрытые таймеры, накопление логов в памяти).
  • Чрезмерно глубокая рекурсия или большой стек вызовов косвенно влияют на память.
  • Нативные аддон-модули или библиотеки, работающие с буферами, неправильно управляют памятью.
  • Запуск в контейнере/CI с ограниченной памятью — процессу просто недаётся достаточно виртуальной памяти.

Типичные сообщения в логах при проблемах с кучей:

  • Reached heap limit allocation failed - javascript heap out of memory
  • Fatal error: call_and_retry_last allocation failed - javascript heap out of memory
  • Fatal error: ineffective mark-compacts near heap limit allocation failed - javascript heap out of memory
  • Fatal error: invalid table size allocation failed - javascript heap out of memory

Быстрый обход: увеличить лимит памяти

Если вам нужно срочно заставить процесс работать — можно увеличить лимит кучи. Это временное решение: оно позволяет запустить сборку или процесс, но не устраняет утечку.

Важно: указывать значение в мегабайтах (MB). Пример для выделения 4 ГБ: 4096 (MB).

Windows — через системные переменные

  1. Откройте меню Пуск, найдите “Дополнительные параметры системы” и откройте соответствующий диалог.
  2. Нажмите “Переменные среды” и создайте новую переменную в System variables или User variables (системная — для всех пользователей, пользовательская — только для текущего аккаунта).
  3. В поле Variable name введите NODE_OPTIONS. В поле Variable value введите –max-old-space-size=4096. Это выделит 4 ГБ виртуальной памяти для Node.js.

Диалог Windows для создания новой переменной окружения с полями имени и значения

  1. Сохраните изменения (OK → Apply → OK), перезапустите терминал/IDE и запускайте проект.

Альтернативы в PowerShell (временное увеличение для текущей сессии):

$env:NODE_OPTIONS="--max-old-space-size=4096"

Или в cmd (временное):

set NODE_OPTIONS=--max-old-space-size=4096

Также можно прямо в командной строке запускать Node с флагом:

node --max-old-space-size=4096 your-script.js

Или в package.json:

"scripts": {
  "start:big": "node --max-old-space-size=4096 index.js"
}

macOS и Linux

В bash/zsh временно для текущего терминала:

export NODE_OPTIONS=--max-old-space-size=4096

Или запуск напрямую:

node --max-old-space-size=4096 index.js

Чтобы сделать изменение постоянным, добавьте export в ~/.bashrc, ~/.zshrc или в файл, где вы настраиваете окружение CI.

Docker и CI

В Dockerfile или при запуске контейнера можно установить переменную окружения:

ENV NODE_OPTIONS=--max-old-space-size=4096

Или при запуске:

docker run -e NODE_OPTIONS=--max-old-space-size=4096 your-image

В CI-системах (GitLab CI, GitHub Actions) задавайте переменную NODE_OPTIONS в настройках пайплайна.

Important: не выделяйте весь объём доступной оперативной памяти хоста процессу — это может привести к вытеснению других сервисов или OOM-гону на уровне ОС.

Как понять: увеличить лимит или лечить утечку?

Решение зависит от причины. Используйте короткую проверочную методику (минимальный план действий):

  1. Попробуйте временно увеличить лимит. Если процесс проходит — скорее всего, потребности памяти в работе большие, но это не исключает утечки.
  2. Сравните поведение при повторных запусках: растёт ли потребление со временем? Утечка проявляет постепенное увеличение.
  3. Сделайте снимок кучи (heap snapshot) и сравните между запусками. Если объём живых объектов растёт — это утечка.
  4. Если причина — единоразовая обработка большого набора данных, подумайте о потоковой обработке (streams) или разбиении задач на чанки.

Пошаговый план диагностики (мини-методология)

  1. Соберите базовые метрики: process.memoryUsage(), uptime, swap usage, контейнерные лимиты.

Пример быстрого вывода внутри приложения:

console.log(process.memoryUsage());
  1. Запустите Node с инспектором для профилирования:
node --inspect --max-old-space-size=4096 index.js
  1. Подключитесь через Chrome DevTools (chrome://inspect) и снимите heap snapshot. Повторите снимок через интервал (например, после N запросов), сравните.

  2. Инструменты: heapdump (пакет для получения снимков), clinic.js (Doctor/Flame), node –prof (V8 профайлер) и llnode для анализа core dump.

  3. Проверьте подозрительные места: глобальные массивы/кэши, long-lived timers, закрытие потоков, обработка больших строк/буферов.

  4. Если используются нативные модули, проверьте их корректность и недавние обновления.

Роли и контрольный список

Разделим обязанности по ролям — это ускорит расследование в команде.

Разработчик:

  • Добавить логирование process.memoryUsage() в критичные участки.
  • Постепенно минимизировать объём одновременно обрабатываемых данных.
  • Провести профилирование и проанализировать heap snapshots.

Оперейшнс (DevOps):

  • Проверить лимиты контейнеров/VM и swap.
  • Настроить метрики (Prometheus/Graphite) на использование памяти.
  • При необходимости временно увеличить NODE_OPTIONS на CI/production.

QA / Тестирование:

  • Создать нагрузочные сценарии, воспроизводящие рост памяти.
  • Автоматизировать проверку при регрессиях: assert памяти в пределах SLO.

Приёмка: тесты и критерии

Критерии приёмки (пример):

  • Приложение стартует и выполняет ключовой сценарий без падения по OOM в течение 30 минут под типичной нагрузкой.
  • Потребление памяти стабилизируется и не показывает линейного роста после N повторов сценария.
  • Важно: при увеличении лимита до X приложение не приводит к OOM всего хоста.

Тест-кейсы:

  • Нагрузочный тест обработки 1000 одновременно открытых соединений/файлов с замером peak RSS.
  • Проверка поведения при обработке большого файла (stream vs buffer).
  • Regression test: повторные запуски скрипта не увеличивают постоянный объём используемой кучи.

Альтернативные подходы и оптимизации

  • Потоковая обработка (streams) вместо загрузки всего файла в память.
  • Разбиение задач на чанки и использование backpressure.
  • Сериализация больших структур на диск/в базу вместо держания в памяти.
  • Использование внешних кэшей (Redis) для больших промежуточных данных.
  • Перевод тяжёлых вычислений в отдельные worker-процессы или в нативный модуль с явным управлением памятью.

Когда увеличение лимита не поможет — примеры

  • Объектные графы продолжают расти при одинаковой нагрузке — классическая утечка.
  • Нативный модуль некорректно освобождает буферы.
  • Фоновая задача накапливает результаты в глобальном массиве без лимита.

В таких случаях увеличение лимита лишь отложит падение системы:

  • Общая рекомендация: фиксировать и тестировать исправление утечки, а не увеличивать лимит на постоянной основе.

Безопасность и приватность при профилировании

Снимки кучи и heapdump содержат объекты и возможные чувствительные данные (строки, пользовательские объекты). Храните и передавайте эти файлы безопасно, удаляйте после анализа и соблюдайте требования конфиденциальности.

План отката (rollback), если после увеличения лимита система нестабильна

  1. Откатить изменение NODE_OPTIONS на предыдущую версию через систему управления конфигурацией.
  2. Перезапустить сервис и мониторить использование памяти и swap в течение 10–30 минут.
  3. Если OOM на хосте — временно уменьшить нагрузку (шардирование, уменьшение параллелизма).
  4. Сообщить команде разработчиков с прикреплёнными логами и снимками кучи.

Полезные сниппеты и команды (cheat sheet)

  • Временно задать для PowerShell:
$env:NODE_OPTIONS="--max-old-space-size=4096"
  • Bash / zsh:
export NODE_OPTIONS=--max-old-space-size=4096
  • Запуск Node с флагом напрямую:
node --max-old-space-size=8192 index.js
  • Логировать потребление памяти в коде:
setInterval(() => console.log(process.memoryUsage()), 60000);
  • Сбор heap snapshot через инспектор: запустите node с –inspect и снимите в Chrome DevTools.

Решение в виде дерева принятия решения

flowchart TD
  A[Появилась ошибка OOM] --> B{Нужно срочно запустить?}
  B -- Да --> C[Увеличить лимит NODE_OPTIONS или --max-old-space-size]
  B -- Нет --> D[Диагностика]
  D --> E[Снять heap snapshot]
  D --> F[Профилировать CPU/память]
  E --> G{Снят баг?}
  G -- Да --> H[Исправить утечку и покрыть тестами]
  G -- Нет --> I[Проверить нативные модули / контейнерные лимиты]

Итоги и рекомендации

  • Увеличение лимита памяти — быстрый и необходимый патч для крупных задач, но не замена отладки.
  • Профилируйте и снимайте heap snapshot, если проблема повторяется или память растёт со временем.
  • Для больших объёмов данных используйте потоковую обработку, чанки и внешние хранилища.
  • В контейнерах учитывайте лимиты хоста и задавайте NODE_OPTIONS атомарно через Docker/CI.

Notes: обязательно храните heap dump в защищённом месте и удаляйте после анализа.

Краткое резюме:

  • Увеличение NODE_OPTIONS помогает запустить задачу сразу.
  • Диагностика и исправление утечек обеспечат стабильность в долгосрочной перспективе.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Игры-опросы в Messenger: как создавать и использовать
Социальные сети

Игры-опросы в Messenger: как создавать и использовать

Google‑вход в Next.js через NextAuth
Аутентификация

Google‑вход в Next.js через NextAuth

Ярлык Windows Tools в Windows 11
Windows

Ярлык Windows Tools в Windows 11

Как удалить комментарии на YouTube
Социальные сети

Как удалить комментарии на YouTube

Как полностью удалить WSL из Windows
Windows

Как полностью удалить WSL из Windows

Как уменьшить слежку Google на Android
Конфиденциальность

Как уменьшить слежку Google на Android