Как исправить ошибку JavaScript heap out of memory в Node.js

Ошибка «JavaScript heap out of memory» часто встречается при запуске больших приложений на Node.js. Она не зависит от ОС — проявляется на Windows, macOS и Linux. В этой статье объясняю, что такое куча (heap), как быстро снять ошибку и как диагностировать коренную причину, чтобы не полагаться на постоянное увеличение памяти.
Что такое heap-память
Heap-память — это динамически выделяемая память, которую использует рантайм и объекты приложения. В отличие от стека, куда помещаются локальные вызовы функций, куча хранит объекты, управляемые сборщиком мусора (GC). Размер кучи влияет на то, сколько объектов одновременно может держать процесс Node.js.
Ключевые моменты:
- Куча динамическая: её размер зависит от виртуальной памяти и настроек V8.
- По умолчанию Node.js использует ограниченный объём кучи; для больших задач этого может не хватать.
- Ошибка может быть вызвана не только малым лимитом, но и утечкой памяти, бесконечными массивами или неправильной рекурсией.
Примеры логов, указывающих на проблему с кучей:
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
Быстрое решение: увеличить лимит памяти
Иногда достаточно увеличить доступный объём кучи. Ниже команды и варианты для разных ОС.
Важно: указывайте объём в мегабайтах. Не выделяйте всю оперативную память под процесс Node — система может стать нестабильной.
Windows — через GUI (переменные среды)
- Откройте меню Пуск и найдите “Дополнительные параметры системы”.
- Откройте диалог системных свойств и нажмите “Переменные среды”.
- Нажмите “Создать” в разделе Переменные пользователя или Системные переменные.
- В поле Имя переменной введите NODE_OPTIONS.
- В поле Значение переменной введите –max-old-space-size=4096 чтобы выделить 4 ГБ.
- Нажмите OK, примените изменения и перезапустите терминал/IDE.
Примечание: чтобы выделить другой объём памяти, умножьте количество ГБ на 1024 и впишите результат в мегабайтах.
Windows — PowerShell (временное)
В PowerShell можно временно установить переменную для текущей сессии:
$env:NODE_OPTIONS="--max-old-space-size=4096"Или для cmd-подобной команды (временная для сессии):
set NODE_OPTIONS=--max-old-space-size=4096После этого запускайте свои скрипты как обычно, например npm run dev.
macOS и Linux
В bash/zsh/fish перед запуском приложения экспортируйте переменную:
export NODE_OPTIONS=--max-old-space-size=4096Или запускайте node прямо с флагом:
node --max-old-space-size=4096 index.jsЧтобы не вводить команду каждый раз, добавьте экспорт в ~/.bashrc, ~/.zshrc или в профиль вашей оболочки.
Примеры использования в package.json
Если вы используете npm-скрипты, можно добавить опцию в команду запуска:
// package.json
{
"scripts": {
"start:large": "node --max-old-space-size=4096 ./dist/index.js"
}
}Для совместимости в разных ОС используйте cross-env или создавайте отдельные скрипты для Windows и Unix-систем.
Когда увеличение памяти не решит проблему
Увеличение кучи — временная мера. Если приложение содержит утечку памяти или неправильно управляет данными, ошибка вернётся при росте нагрузки.
Примеры ситуаций, когда увеличение объёма не поможет:
- Постоянный рост используемой памяти (утечка).
- Накопление больших массивов или буферов без очистки.
- Некорректное использование кешей, global-объектов или синглтонов.
Диагностика и устранение корня проблемы
Ниже методология и инструменты для анализа причин превышения кучи.
Мини-методология — шаги
- Воспроизведите проблему локально с близкой нагрузкой.
- Запустите с небольшим увеличением кучи, чтобы исключить немедленное падение.
- Создайте снимок (heap snapshot) и сравните его между запусками.
- Используйте профилирование CPU/Memory для поиска горячих точек.
- Исправьте утечку или уменьшите потребление (пагинация, потоковая обработка).
- Нагрузочное тестирование после исправления.
Инструменты
- Chrome DevTools / node –inspect для создания heap snapshot.
- node –inspect-brk и профилировщик памяти в DevTools.
- npm пакеты: heapdump, clinic.js, memwatch-next (с осторожностью).
- Мониторинг: PM2, New Relic, Datadog — для отслеживания роста RSS и heapUsed.
Как получить снимок кучи
- Запустите node с –inspect.
- Откройте chrome://inspect в Chrome и подключитесь к процессу.
- Вкладка Memory -> Take Heap Snapshot.
- Сравните снимки: ищите объекты, которые постоянно наращиваются.
Хаки и альтернативные подходы
- Используйте стриминг и парсинг по частям вместо загрузки больших файлов в память.
- Применяйте генераторы и итераторы для ленивой обработки коллекций.
- Очистка кеша по времени (TTL) или по размеру.
- Горизонтальное масштабирование: распараллеливайте работу на несколько процессов/серверов.
Роль-based чек-листы
Разработчик:
- Построить воспроизводимый кейс.
- Сделать heap snapshot до и после действия.
- Поискать глобальные переменные и большие массивы.
DevOps/Инженер по релизам:
- Настроить мониторинг RSS/heapUsed.
- Запланировать авто-перезапуск через process manager (PM2) с уведомлением.
- Убедиться, что на сервере достаточно свободной памяти.
QA:
- Провести стресс-тестирование с постепенным увеличением нагрузки.
- Валидировать исправление в production-like окружении.
Примеры конфигураций и сниппеты
Запуск сервера с лимитом 6 ГБ:
node --max-old-space-size=6144 ./server.jsДля Docker можно установить переменную NODE_OPTIONS в Dockerfile или docker-compose:
# Dockerfile
ENV NODE_OPTIONS=--max-old-space-size=4096Быстрая таблица принятия решений
flowchart TD
A[Появилась ошибка heap out of memory] --> B{Можно ли временно увеличить память?}
B -- Да --> C[Установить NODE_OPTIONS или флаг node]
B -- Нет --> D[Диагностика утечки памяти]
D --> E[Сделать heap snapshot]
E --> F{Найдены возрастающие объекты?}
F -- Да --> G[Исправить код: очистка, стриминг]
F -- Нет --> H[Проверить конфигурацию окружения и зависимости]
G --> I[Тестирование]
H --> IКритерии приёмки
- Приложение не падает с ошибкой heap out of memory при тестовой нагрузке.
- Загрузка памяти остаётся стабильной и предсказуемой (после сборок мусора).
- Мониторинг оповещает о росте памяти до заданного порога.
Важные замечания
Важно: не полагайтесь на увеличение лимита как на постоянное решение. Утечка памяти — продукт ошибки в коде, и её надо устранить.
Примечание: 32‑битные сборки Node имеют меньшие лимиты кучи по сравнению с 64‑битными. При интенсивной работе используйте 64‑битные сборки.
Краткое резюме
Увеличение NODE_OPTIONS/–max-old-space-size — быстрый способ снять симптом. Для устойчивого решения используйте профилирование, снимки кучи и устранение утечек. Настройте мониторинг и автоматическое уведомление, чтобы ловить рост памяти до падения сервиса.
Похожие материалы
Как устроить идеальную вечеринку для просмотра ТВ
Как распаковать несколько RAR‑файлов сразу
Приватный просмотр в Linux: как и зачем
Windows 11 не видит iPod — способы исправить
PS5: как настроить игровые пресеты