Ошибка «Heap out of memory» в JavaScript возникает когда приложению недостаточно памяти. В этой статье мы разберемся как быстро исправить эту ошибку.
Самый быстрый способ — увеличить количество памяти в Node.js. Начиная с версии v8 вы можете устанавливать ограничение в мегабайтах с помощью флага --max-old-space-size
:
node --max-old-space-size=4096 index.js
Вы можете установить любое ограничение, но не используйте всю доступную память, иначе может произойти крэш системы.
Аналогичного эффекта можно добиться с помощью другого флага:
NODE_OPTIONS="--max-old-space-size=4096" node index.js
Изменение ограничения памяти для всей среды Node.js
Чтобы изменить лимит памяти для всей среды, нужно установить значение переменной NODE_OPTIONS в конфигурационном файле (его расширение .bashrc, bash_profile или .zshrc и т. п.).
export NODE_OPTIONS=--max_old_space_size=4096
«Heap out of memory» во время nmp install
Если во время установки пакетов с помощью npn или yarn у вас появляется эта ошибка, вы можете увеличить лимит памяти на время установки.
node --max-old-space-size=4096 $(which npm) install -g nextawesomelib
Что означает эта ошибка?
По умолчанию в Node.js установлен лимит памяти, который не позволяет программе занять слишком много памяти и уронить всю систему. Лимит отличается на разных версиях Node.js и архитектурах (32бита или 64бита).
Ограничения памяти на разных версиях Node.js
Эти значения не объявлены официально, но с помощью небольшой программы можно получить такие значения для 64 битной архитектуры.
4GB памяти в куче будет достаточно для большинства случаев
Чтобы проверить лимит памяти вашей системы, создайте файл index.js и добавьте в него следующий код:
const array = [];
while (true) {
// увеличение массива на каждой итерации
array.push(new Array(10000000));
const memory = process.memoryUsage();
console.log((memory.heapUsed / 1024 / 1024 / 1024).toFixed(4), 'GB');
}
Как избежать недостатка памяти в Node.js
Увеличение лимита памяти поможет быстро исправить проблему, но этого может быть недостаточно. В следующий раз память системы может закончиться. В любом случае стоит выяснить источник проблемы.
Вот три альтернативных решения, которые позволят уменьшить потребление памяти.
Обработка данных по частям
Иногда нужно обработать большой набор данных. Например, вы пишите программу, которая принимает данные из CSV файла, очищает их и добавляет в БД (это называется ETL: извлечение, трансформация, загрузка).
Если в такой ситуации программе начинает не хватать памяти, попробуйте разделить данные на несколько частей.
# split -l numberoflines filename
split -l 1000000 users.csv
Подробнее о том, как сделать это в MongoDB в этом ответе на StackOverflow.
Избегайте утечек памяти
В этой статье объясняется, как работает управление памятью в JavaScript, и как избежать большинства возможных утечек.
Её содержание сводится к тому, что большинство утечек, которые можно отследить, вызваны неудалёнными ссылками на объекты, которые больше не нужны. Это может случиться, когда вы забыли удалить interval, timer или чрезмерно используете глобальные переменные.
Профилирование
Профилирование помогает обнаружить утечки памяти. На фронтенде это можно сделать в Chrome в Инструментах разработчика во вкладке Memory.
В Node.js начиная с версии 6.3.0 также можно использовать Chrome для отладки использования памяти.
Во-первых, запустите приложение в режиме проверки:
node --inspect index.js
Затем откройте страницу в Chrome, введите адрес chrome://inspect
и нажмите на кнопку Open dedicated DevTools for Node.
После этого откроется окно, в котором вы сможете подключиться к вашему Node.js приложению.
Перезапуск процессов
Допустим, ваша программа работает на компьютере с ограниченным объёмом памяти, например Raspberry Pi.
Мы будем использовать cluster и библиотеки node v8.
Cluster даёт возможность воспользоваться преимуществами многоядерных систем и запускать кластер из процессов Node.js.
V8 предоставляет API для конкретной версии V8, используемой в Node.js.
Давайте разделим программу на две сущности: master и worker.
Master будет перезапускать worker`ов в случае, если они перестанут работать из-за переполнения кучи. Worker`ы будут отвечать за основную логику (в нашем случае запускать тяжёлую функцию heavyHeapConsumer).
const cluster = require('cluster');
const v8 = require('v8');
let heavyHeapConsumer = () => {
let arrays = [];
setInterval(() => {
arrays.push(new Array(1000000));
}, 100);
};
if (cluster.isMaster) {
cluster.fork();
cluster.on('exit', (deadWorker, code, signal) => {
// Перезапуск worker`а
let worker = cluster.fork();
// Сохранение id процесса
let newPID = worker.process.pid;
let oldPID = deadWorker.process.pid;
// Логгирование
console.log('worker ' + oldPID + ' died.');
console.log('worker ' + newPID + ' born.');
});
} else { // worker
const initialStats = v8.getHeapStatistics();
const totalHeapSizeThreshold =
initialStats.heap_size_limit * 85 / 100;
console.log("totalHeapSizeThreshold: " + totalHeapSizeThreshold);
let detectHeapOverflow = () => {
let stats = v8.getHeapStatistics();
console.log("total_heap_size: " + (stats.total_heap_size));
if ((stats.total_heap_size) > totalHeapSizeThreshold) {
process.exit();
}
};
setInterval(detectHeapOverflow, 1000);
// выполнение основной логики
heavyHeapConsumer();
}
При первом запуске приложения создается worker и подписка на событие exit, при срабатывании которой создаётся новый worker, и событие логгируется.
total_heap_size — размер кучи, который можно увеличить.
heap_size_limit — максимально возможный размер кучи.
В коде worker`а устанавливается total_heap_size равный 85% от heap_size_limit. Затем worker каждую секунду проверяет не превышен ли лимит. Если лимит превышен, то процесс worker убивает себя.
Лимит (85%) и интервал проверки (1 секунда) нужно выбирать для каждого конкретного случая. Здесь функция heavyHeapConsumer увеличивает кучу каждые 100мс. Если в вашем варианте увеличение будет происходить каждые 10мс, то следует уменьшить лимит и увеличить интервал проверки.
Полный код примера доступен на GitHub.
Источники JavaScript Heap Out Of Memory Error,
Detect heap overflow on Node.js: JavaScript heap out of memory
Недавно в компании Reside Real Estate столкнулись с проблемами: в самые ответственные моменты начал падать Node.js-сервер. Подозрение пало на память. Сотрудники компании прибегли к временным мерам, что позволило избавить от неудобств пользователей, и занялись поисками источника проблем. В результате им удалось найти и устранить неполадки.
В этом материале они рассказывают о том, как искать и устранять ошибки, связанные с использованием памяти. А именно, речь пойдёт об утечках памяти, и о ситуациях, когда программы используют гораздо больше памяти, чем им на самом деле нужно. Этот рассказ поможет тем, кто столкнётся с чем-то похожим, сразу понять причину странного поведения сервера и быстро вернуть его в строй.
Типы проблем с памятью
▍ Утечка памяти
В информатике утечка памяти — это разновидность неконтролируемого использования ресурсов, которая возникает, когда программа неправильно управляет выделением памяти, в результате чего память, которая больше не нужна, не освобождается.
В низкоуровневых языках вроде C утечки памяти часто возникают в ситуации, когда память выделяют, например так: buffer = malloc(num_items*sizeof(double));
, но не освобождают после того, как память больше не нужна: free(buffer);
.
В языках с автоматическим управлением освобождением памяти утечки возникают, когда к сущностям, которые больше не нужны, можно получить доступ из исполняющейся программы, или из некоего корневого объекта. В случае с JavaScript, любой объект, к которому можно обратиться из программы, не уничтожается сборщиком мусора, соответственно, место, которое он занимает в куче, не освобождается. Если размер кучи вырастет слишком сильно, возникнет ситуация нехватки памяти.
▍ Чрезмерное использование памяти
В ситуации чрезмерного использования памяти программа занимает гораздо больше памяти, чем ей нужно для решения возложенной на неё задачи. Например, такое может возникнуть тогда, когда ссылки на большие объекты хранят дольше, чем нужно для правильной работы программы, что предотвращает уничтожение этих объектов сборщиком мусора. Подобное случается и тогда, когда в памяти держат большие объекты, которые попросту не нужны программе (это вызывает одну из двух основных проблем, которые мы рассмотрим ниже).
Выявление проблем с памятью
Наши проблемы с памятью проявляли себя вполне очевидным образом, в основном — в виде этого мрачного сообщения из журнала:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Признаки утечки памяти, кроме того, включают в себя уменьшение производительности программы с течением времени. Если сервер периодически выполняет один и тот же процесс, который изначально быстр, а перед отказом постепенно становится медленнее, это, весьма вероятно, говорит об утечке памяти.
Признаки чрезмерного использования памяти обычно выражаются в низкой производительности программ. Однако, чрезмерное использование памяти без утечки со временем не приводит к падению производительности.
Временное решение проблемы
Часто, когда что-то случилось, нет времени на то, чтобы понять суть проблемы и всё исправить. У нас его точно не было. К счастью, есть способы увеличения объёма памяти, выделенной процессу Node. У движка V8 имеется стандартное ограничение памяти равное примерно 1.5 Гб на 64-битных компьютерах. Даже если вы запускаете процесс Node на компьютере, имеющем гораздо больше RAM, это роли не играет, если только вы не увеличите этот лимит. Для того, чтобы увеличить лимит, можно передать процессу Node ключ max_old_space_size
. Выглядит это так:
node --max_old_space_size=$SIZE server.js
Параметр $SIZE
задаётся в мегабайтах и, теоретически, может быть любым числом, которое имеет смысл на конкретном компьютере. В нашем случае был использован параметр 8000, который, с учётом особенностей работы сервера, позволил выиграть достаточно времени на исследования. Кроме того, мы увеличили динамическую память. Мы пользуемся Heroku, там это делается просто.
Также мы воспользовались сервисом Twilio, настроили его так, чтобы нас оповещали каждый раз, когда на сервер приходит запрос, требующий особенно много памяти. Это позволило нам наблюдать за запросом и перезапускать сервер после его завершения. Такое решение неидеально, но для того, чтобы наши пользователи не сталкивались с отказами, мы были готовы на всё, даже на круглосуточные дежурства без выходных.
Отладка
Итак, благодаря настройкам Node и организации мониторинга сервера мы выиграли время, которое можно было потратить на то, чтобы дойти до первопричины неполадки. На первый взгляд может показаться, что «проблема с памятью сервера» — это нечто ужасное, а для избавления от этой «проблемы» потребуются фантастические инструменты и умения. Однако, на самом деле, всё не так уж и страшно. Есть вполне доступные инструменты для исследования приложений, существует множество материалов, в которых можно найти подсказки. Мы, для исследования памяти Node-сервера, будем пользоваться инструментами разработчика Chrome.
▍ Снепшот кучи
«Утечка памяти» — это проблема, которая выражается в постоянно растущем размере кучи. В результате куча оказывается слишком большой для продолжения нормальной работы сервера. Поэтому в самом начале исследования нужно сделать несколько снепшотов (снимков состояния) кучи, с некоторым интервалом, и погрузиться в исследование этих снепшотов с использованием инструментов разработчика Chrome для того, чтобы понять, почему куча так велика и почему она растёт. Обратите внимание на то, что следует делать несколько снепшотов, через некоторое время, в результате можно будет изучить объекты, которые будут переходить из одного снепшота в другой. Эти объекты, вполне возможно, являются виновниками утечки памяти. Существует множество способов создать снепшот кучи.
▍ Использование heapdump для создания снепшотов кучи
Мы, для создания снимков кучи, пользовались heapdump. Этот npm-пакет оказался весьма полезным. Его можно импортировать в код и обращаться к нему в тех местах программы, где нужно делать снепшоты. Например, мы делали снепшот каждый раз, когда сервер получал запрос, который мог вызвать процесс, интенсивно использующий память. Тут же мы формировали имя файла, содержащее текущее время. Таким образом мы могли воспроизводить проблему, отправляя на сервер всё новые и новые запросы. Вот как это выглядит в коде:
import heapdump from 'heapdump';
export const handleUserRequest = (req) => {
heapdump.writeSnapshot(
`1.User_Request_Received-${Date.now()}.heapsnapshot`,
(err, filename) => {
console.log('dump written to', filename);
});
return startMemoryIntensiveProcess(req);
};
▍ Использование удалённого отладчика Chrome для создания снепшотов кучи
Если вы работаете с Node 6.3. или с более поздней его версией, для создания снепшотов кучи можно использовать удалённый отладчик Chrome. Для того, чтобы это сделать, сначала запустите Node командой такого вида: node --inspect server.j
s. Затем перейдите по адресу chrome://inspect
. Теперь вы сможете удалённо отлаживать процессы Node. Чтобы сэкономить время, можете установить этот плагин Chrome, который автоматически откроет вкладку отладчика при запуске Node с флагом --inspect
. После этого просто делайте снепшоты тогда, когда сочтёте это необходимым.
Средства удалённой отладки Chrome и создание снепшотов кучи
Загрузка снепшотов и определение типа проблемы с памятью
Следующий шаг заключается в загрузке снепшотов на закладке Memory (память) инструментов разработчика Chrome. Если вы использовали для создания снепшотов кучи удалённый отладчик Chrome, то они уже будут загружены. Если вы использовали heapdump, то вам понадобится загрузить их самостоятельно. Обязательно загружайте их в правильном порядке, а именно — в том, в котором они были сделаны.
Самое главное, на что надо обращать внимание на данном этапе работы, заключатся в том, чтобы понять — с чем именно вы столкнулись — с утечкой или с чрезмерным использованием памяти. Если перед вами утечка памяти, то вы, вероятно, уже получили достаточно данных для того, чтобы начать исследовать кучу в поисках источника проблемы. Однако, если перед вами — чрезмерное использование памяти, вам нужно попробовать некоторые другие методы анализа для того, чтобы получить содержательные данные.
Наша первая проблема с памятью выглядела, на закладке Memory инструментов разработчика Chrome, так, как показано ниже. Несложно заметить, что куча постоянно растёт. Это говорит об утечке памяти.
Куча увеличивается со временем — очевидная утечка памяти
Наша вторая проблема с памятью, которая возникла через пару месяцев после исправления утечки, в итоге, на тех же испытаниях, выглядела так, как показано на рисунке ниже.
Куча со временем не растёт — это не утечка памяти
Размер кучи со временем не меняется. Всё дело в том, что при чрезмерном использовании памяти её размер превышает некие ожидаемые показатели не всегда, а лишь при выполнении определённых операций. При этом снепшоты делаются в какие-то моменты, которые никак не привязаны к ситуациям с чрезмерным использованием памяти. Если в момент создания снепшота не происходило выполнения неправильно написанной ресурсоёмкой функции, тогда куча не будет содержать никакой ценной информации о памяти, используемой этой функцией.
Для выявления подобных проблем мы рекомендуем два способа, которые помогли нам обнаружить виновников проблемы — функцию и переменную. Это — запись профиля выделения памяти и создание снепшотов на сервере, находящемся под серьёзной нагрузкой.
Если вы используете версию Node 6.3 или более позднюю, вы можете записать профиль выделения памяти через удалённый отладчик Chrome, запустив Node с уже упоминавшимся ключом --inspect
. Это даст сведения о том, как отдельные функции используют память с течением времени.
Запись профиля выделения памяти
Ещё один вариант заключается в отправке множества одновременных запросов к вашему серверу и в создании множества снепшотов во время обработки этих запросов (предполагается, что сервер работает асинхронно, как результат, некоторые снепшоты могут оказаться гораздо больше других, что укажет на проблему). Мы бомбардировали сервер запросами и делали снепшоты. Некоторые из них оказались очень большими. Исследованием этих снепшотов можно заняться для выявления источника проблемы.
Анализ снепшотов
Теперь у нас есть данные, которые вполне могут помочь найти виновников проблем с памятью. В частности, рассмотрим анализ ситуации, в которой размеры последовательно сделанных снепшотов растут. Вот один из снепшотов, который загружен на вкладке Memory инструментов разработчика Chrome.
Исследование утечки памяти — все функции указывают на наш сервис электронной почты
Показатель Retained Size — это размер памяти, освобождённой после того, как объект удалён вместе со своими зависимыми объектами, которые недостижимы из корневого объекта.
Анализ можно начать с сортировки списка по убыванию по параметру Retained Size, после чего приступить к исследованию больших объектов. В нашем случае имена функций указали нам на ту часть кода, которая вызывала проблему.
Так как мы были уверены в том, что перед нами утечка памяти, мы знали, что исследование стоит начать с поиска переменных с неподходящей областью видимости. Мы открыли файл index.js
почтовой службы и тут же обнаружили переменную уровня модуля в верхней части файла.
const timers = {};
Мы со всем этим разобрались, внесли необходимые изменения, протестировали проект ещё несколько раз и исправили в итоге утечку памяти.
Вторую проблему отлаживать было сложнее, но тут сработал тот же подход. Ниже показан профиль выделения памяти, который мы записали с использованием инструментов разработчика Chrome и ключа Node --inspect
.
Поиск виновников чрезмерного использования памяти
Так же как при анализе данных в ходе поиска утечки памяти, многие имена функций и объектов с первого взгляда узнать не удаётся, так как находятся они на более низком уровне, чем код, который пишут для Node.js. В подобной ситуации следует, встретив незнакомое имя, записать его.
Профиль выделения памяти привёл нас к одной из функций, recordFromSnapshot
, она стала хорошей отправной точкой. Наше исследование снепшота кучи, которое не особенно отличалось от исследования, выполняемого при поиске утечки памяти, позволило обнаружить очень большой объект target
. Это была переменная, объявленная внутри функции recordFromSnapshot
. Эта переменная осталась от старой версии приложения, она была больше не нужна. Избавившись от неё, мы исправили ситуацию с чрезмерным использованием памяти и ускорили выполнение процесса, которое раньше занимало 40 секунд, до примерно 10 секунд. При этом процессу не требовалась дополнительная память.
Итоги
Две вышеописанные проблемы с памятью заставили нас притормозить развитие нашего проекта, которое до этого шло очень быстро, и проанализировать производительность сервера. Теперь мы понимаем особенности производительности сервера на гораздо более глубоком уровне, чем раньше, и мы знаем, сколько времени нужно для нормального выполнения отдельных функций, и сколько памяти они используют. У нас появилось гораздо лучшее понимание того, какие ресурсы нам нужны при дальнейшем масштабировании проекта. И, что самое важное, мы перестали бояться проблем с памятью и перестали ожидать их появления в будущем.
Уважаемые читатели! Сталкивались ли вы с проблемами, связанными с памятью в Node.js? Если да — просим рассказать о том, как вы их решали.
When running JavaScript process using Node, you may see an error that stops the running process.
The fatal error says JavaScript heap out of memory as seen below:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Sometimes, it also has alternative error message like this:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Both errors above occur when JavaScript has a lot of processes to handle, and the default allocated memory by Node is not enough to finish the running process.
An example of this error can be found when you have to build the packages you installed using npm install
with the node-gyp library.
The default Node memory limit varies from version to version, but the latest Node version 15 still has a memory limit below 2GB.
Solve JavaScript heap out of memory error
To fix JavaScript heap out of memory error, you need to add the --max-old-space-size
option when running your npm command.
Here’s an example of increasing the memory limit to 4GB:
node --max-old-space-size=4096 index.js
If you want to add the option when running the npm install
command, then you can pass the option from Node to npm as follows:
node --max-old-space-size=4096 `which npm` install
If you still see the heap out of memory error, then you may need to increase the heap size even more. The memory size starts from 1024
for 1GB:
--max-old-space-size=1024 # increase memory to 1GB
--max-old-space-size=2048 # increase memory to 2GB
--max-old-space-size=3072 # increase memory to 3GB
--max-old-space-size=4096 # increase memory to 4GB
--max-old-space-size=8192 # increase memory to 8GB
Alternatively, you can also set the memory limit for your entire environment using a configuration file.
Set Node memory limit using configuration file
You can set the default memory limit using your terminal client’s configuration file.
If you’re using Bash, then add the following line to your .bashrc
file:
export NODE_OPTIONS=--max_old_space_size=4096 #4GB
When you’re using ZSH, then add the line above to the .zshrc
file.
Don’t forget to check the available memory in your machine before increasing the memory limit.
Too much memory allocated for Node may cause your machine to hang.
Why JavaScript heap out of memory occurs?
Before the creation of Node, JavaScript’s role in web development is limited to manipulating DOM elements in order to create an interactive experience for the users of your web application.
But after the release of Node, JavaScript suddenly had a back-end architecture, where you can run complex database queries and other heavy processing before sending data back to the front-end.
JavaScript also saw the rise of npm that allows you to download libraries and modules like React and Lodash.
Many modules downloaded from npm have lots of dependencies on other modules, and some may need to be compiled before they can be used.
Node memory usage will increase as you have more tasks to process. This is why JavaScript may have a heap out of memory error today.
Table of Contents
Hide
- What is fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory?
- How to fix fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory?
- Solution 1 – Install Latest Node Version
- Solution 2 – Increase the Memory Size using export
- Solution 3 – Set the memory through NODE_OPTIONS
- Conclusion
The fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory occurs if there is any memory leak or the application consumes a lot of memory.
In this article, we will look at what exactly is the fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory means and how to resolve this error.
If you are building and running the application on Node.JS version 10, and if you have any kind of memory leak in the code, it can lead to javascript heap out of memory.
It can also happen if the application consumes too much memory and mainly while processing extensive data.
The memory management in Node V10 is entirely different when compared to the latest version, and by default, 512 MB of memory/heap size is allocated in Node 10. If the application crosses this size, it will result in a javascript heap out of memory.
How to fix fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory?
We can resolve this issue by installing the latest Node version or by increasing the default allocated memory size. Also, you need to check if there is any memory leak in the application.
Solution 1 – Install Latest Node Version
The Node 10 has a different way of memory allocation, and by default, the max size set is 512MB. Hence you can install the latest LTS Node 12/16 to resolve the issue.
Solution 2 – Increase the Memory Size using export
Increasing the default memory size will fix the issue; you could increase the memory allocation by running the below command.
The size can be of any number according to the needs, the below command is just an indicative examples on how to increase the memory size.
export NODE_OPTIONS="--max-old-space-size=5120" # Increases to 5 GB
export NODE_OPTIONS="--max-old-space-size=6144" # Increases to 6 GB
export NODE_OPTIONS="--max-old-space-size=7168" # Increases to 7 GB
export NODE_OPTIONS="--max-old-space-size=8192" # Increases to 8 GB
Solution 3 – Set the memory through NODE_OPTIONS
We can change the default memory size using the set NODE_OPTIONS
as shown below.
set NODE_OPTIONS=--max_old_space_size=4096
Note: All the solution above works effectively, but you should always ensure there is no memory leak on your application first before changing these values and also ensure you have the free memory space left.
Conclusion
The fatal error: ineffective mark-compacts near heap limit allocation failed – javascript heap out of memory happens when you run the application with Node 10 version, and your application consumes more than 512MB memory.
We can resolve the issue by upgrading to the latest version of Node as the memory allocation is managed efficiently. Alternatively, we can increase the default memory size using the NODE_OPTIONS
.
Srinivas Ramakrishna is a Solution Architect and has 14+ Years of Experience in the Software Industry. He has published many articles on Medium, Hackernoon, dev.to and solved many problems in StackOverflow. He has core expertise in various technologies such as Microsoft .NET Core, Python, Node.JS, JavaScript, Cloud (Azure), RDBMS (MSSQL), React, Powershell, etc.
Sign Up for Our Newsletters
Subscribe to get notified of the latest articles. We will never spam you. Be a part of our ever-growing community.
By checking this box, you confirm that you have read and are agreeing to our terms of use regarding the storage of the data submitted through this form.
A common problem while working on a JavaScript Node.js project is the “JavaScript heap out of memory” error. This error usually occurs when the default memory allocated by your system to Node.js is not enough to run a large project.
The error is common whether you run your project on Windows, macOS, or a Linux distribution like Ubuntu. Luckily, there are a few easy fixes that can help resolve the “JavaScript heap out of memory” error.
What Is Heap Memory?
Before you look at fixing the error, it’s useful to understand what heap memory is and how programs use it.
Memory allocated on the system heap is also called dynamically allocated memory. It’s up to the programmer to use the available memory as they see fit. More importantly, the heap size for a program depends on the available virtual memory allocated to it.
If you’re running a relatively-large project, it may require more memory than the default allocated chunk. This may cause your project to crash and log the “JavaScript heap out of memory” error.
How to Fix JavaScript Heap Out of Memory on Windows
Regardless of your IDE, the “JavaScript heap out of memory” fix is identical.
You can add an environment variable through Control Panel to increase the memory allocated to a Node.js project.
- Open the Start menu, search for Advanced System Settings, and select the Best match.
- From the dialog box, click on Environment Variables, then click on New from either System variables or User variables. The former applies to all users on your computer, while the latter affects just your current account
- In the Variable name field enter NODE_OPTIONS. In the Variable value field enter —max-old-space-size=4096. This value will allocate 4GB of virtual memory to Node.js. To set a different value, multiply the amount you require in GB by 1024 (the variable value needs to be in MB).
- Click on OK to save your changes, then click Apply and finally click OK once more. Restart your project for the changes to take effect.
You can also set an environment variable through a Windows PowerShell terminal.
Launch a PowerShell terminal, type the below command and press Enter:
$env:NODE_OPTIONS="--max-old-space-size=4096"
If you only want to increase the heap memory temporarily, run the below command in a PowerShell terminal before running your project:
set NODE_OPTIONS=--max-old-space-size=4096
Once you’ve entered this command, you can deploy/run your project using npm run dev or your own script.
Remember always to enter the required memory size in MB. Not doing so can cause unexpected behavior in your program. It is also vital not to allocate your entire available memory as this can cause a significant system failure.
How to Fix JavaScript Heap Out of Memory Error on macOS and Linux
On macOS and Linux, the heap memory fix is very similar. You should export an environment variable that specifies the amount of virtual memory allocated to Node.js.
In your terminal, before you run your project, enter the following command and press Enter:
export NODE_OPTIONS=--max-old-space-size=4096
This will allocate 4GB of virtual memory to the execution space of Node.js. To set a different amount of memory, replace 4096 with the required amount in MB.
You can add the above command to your configuration file to avoid repeating the process. To do so, follow the same process for setting your PATH variable.
Avoid JavaScript Heap Out of Memory Error
You can avoid this error by ensuring your program is free of memory leaks. Proper memory management is crucial when writing your programs, especially in a low-level language.
While increasing the allocated memory will temporarily fix the problem, you should find the root cause and fix it.
In this article, we’ll discuss, how to resolve the “JavaScript heap out of memory” which we face due to insufficient memory allocated to Javascript operations.
This Angular tutorial is compatible with version 4+ including latest version 12, 11, 10, 9, 8 ,7, 6 & 5.
Sometime back I faced a similar kind of issue while working on my Angular project.
Like normal day to day tasks I executed the “ng serve --open
” command to run my project in the browser, but suddenly I faced a very strange issue which looked as shown below:
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 00007FF72C01B49D]
1: StubFrame [pc: 00007FF72BFA1941]
Security context: 0x02873e7c08d1 <JSObject>
2: addMappingWithCode [00000302E7B35E09] [C:projectsmy-appnode_moduleswebpack-sourcesnode_modulessource-maplibsource-node.js:~150] [pc=000003C998902E57](this=0x03734f5422c9 <GlobalObject Object map = 00000030A7C4D729>,0x0084f88491f1 <Object map = 0000010F223E55F9>,0...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF72B405F0F napi_wrap+114095
2: 00007FF72B3B0B96 v8::base::CPU::has_sse+66998
3: 00007FF72B3B1996 v8::base::CPU::has_sse+70582
4: 00007FF72BBC6E9E v8::Isolate::ReportExternalAllocationLimitReached+94
5: 00007FF72BBAEF71 v8::SharedArrayBuffer::Externalize+833
6: 00007FF72BA7B1DC v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1436
7: 00007FF72BA86410 v8::internal::Heap::ProtectUnprotectedMemoryChunks+1312
8: 00007FF72BA82F34 v8::internal::Heap::PageFlagsAreConsistent+3204
9: 00007FF72BA78733 v8::internal::Heap::CollectGarbage+1283
10: 00007FF72BA76DA4 v8::internal::Heap::AddRetainedMap+2452
11: 00007FF72BA980ED v8::internal::Factory::NewFillerObject+61
12: 00007FF72B7FE231 v8::internal::interpreter::JumpTableTargetOffsets::iterator::operator=+1665
13: 00007FF72C01B49D v8::internal::SetupIsolateDelegate::SetupHeap+546637
14: 00007FF72BFA1941 v8::internal::SetupIsolateDelegate::SetupHeap+48113
15: 000003C998902E57
npm ERR! code ELIFECYCLE
npm ERR! errno 134
npm ERR! `ng serve -o`
npm ERR! Exit status 134
What’s this issue?
This issue appeared due to lots of packages modules were getting used in my application project due to which the javascript engine was not getting enough allocated memory to perform some temporary stuff like compiling the source code and building the source bundles.
How to resolve this issue?
To resolve this issue, we need to allocate more space for node operations. You can add a configuration inside the package.json npm scripts as shown below:
we generally have this command in the “scripts
” property of the package.json :
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
So we need to update the commonly used scripts like “start
“, “build
” etc as shown below:
"scripts": {
"ng": "ng",
"start": "node --max_old_space_size=2192 ./node_modules/@angular/cli/bin/ng serve",
"build": "node --max_old_space_size=2192 ./node_modules/@angular/cli/bin/ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
You can notice above, we’ve added the node command with space allocation configuration allocating 2GB of data for our node operation.
If you face the “JavaScript heap out of memory” issue again try increasing the space to 4192 or 8192 etc.
Hope this will resolve the issue….
JavaScript heap out of memory is a common issue that occurs when there are a lot of processes happening concurrently. The default JavaScript heap size allocated by Node.js requires additional space to smoothly run its operations; thus, creating a JavaScript issue.
In this article, we will be discussing JavaScript memory and how to clear some space, so let’s dive right into it.
JavaScript Out of Memory: Solving the Issue
To solve JavaScript heap size, we must maximize space before running the script. In other computer languages, there are manual management options such as free() and malloc(). However, JavaScript heap size allocates memory during the creation of objects. This JavaScript free memory is available once objects are sent to garbage, or when not in use.
To understand the JavaScript memory issue better, let’s see an example of a JavaScript heap size warning. Refer to the following error:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed – JavaScript heap out of memory
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed – JavaScript heap out of memory
– Explaining the Memory Heap Issue
The example shown above is a common sight when working with large projects. The default JavaScript heap size allocated by node gets overburdened and commands are not effectively completed.
This can also occur if there are a lot of modules to npm install from the package.json file.
Fixing JavaScript Memory
The easiest way to JavaScript free memory is by increasing the memory allocated to a command and running it before starting with the project. Below, we can see the effect on macOS and Windows operations. Do note that Linux users can tally macOS as their go-to method.
– In Windows
To increase the allocation of JavaScript memory in Windows, follow these steps:
- Go to control panel
- Head over to System
- In the system menu, click on Advanced System Settings
- You should see an option named variables, so please go ahead and click that option
- Now, click on new user or new system
- Once you add the variable name and value, clicking on “ok” will get the job done.
Alternatively, we can also use powershell, which we will explain below.
Powershell Method
Through the Powershell method, we can increase the memory if needed. For larger projects, we can add a ceiling of as much as 12-14 GB, considering the project is large enough. The following example shows a code application through powershell:
$env:NODE_OPTIONS=”–max-old-space-size=Desiredvalue”
– MacOS
Do note that even the latest node versions have a memory limit below two gigabytes (GB). In the example below, we used the –max-old-space-size option, as you can see:
sampleproject test
export NODE_OPTIONS=–max-old-space-size=Desiredvalue
sampleproject monitor
Let’s see some more examples for a better understanding.
– More Examples Increasing Memory in MacOs
Node versions default storage of two GB can be increased, so let’s go ahead and try to increase the limit around four GB in the example below:
node –max-old-space-size=4096 index.js
Increasing Memory During NPM Install
In some cases, we might want to add this node to the NPM install. Here is how you can do it if you prefer so:
node –max-old-space-size=4096 `which npm` install
– Increasing Memory In Ranges
Sometimes, a project needs more than a four GB JavaScript memory. To increase it even further, we can use a greater JavaScript heap size, starting from a single GB and continuing to four GB. You can see how we’ve done that in the following example:
–max-old-space-size=2048
–max-old-space-size=3072
–max-old-space-size=4096
From the example shown above, we started from one GB and continued until we increased the memory to four GB.
Pros and Cons of Node.js in JavaScript: Allocating the Heap Size
As Node.js is an important concept, let’s briefly discuss its benefits and drawbacks.
– Benefits of Node.js in JavaScript
Some of the benefits of Node.js are as follows:
- Scaling of applications is done in horizontal and vertical direction.
- We can add extra resources to the nodes, an option not provided by other JavaScript servers.
- Node.js is easy-to-use at the backend and conserves time.
- It helps write server-side applications; thus, both frontend and backend applications work in a runtime environment.
- Node.js serves both the client and the server-side applications since it is a full-stack development model.
- JavaScript code is interpreted by Node.js through Google’s V8 JavaScript engine, making it faster in its operations.
– Drawbacks of Node.js in JavaScript
Moreover, here are some of the drawbacks of Node.js:
- The Application Programming Interface (API) keeps changing at frequent intervals, compromising on stability.
- Compared to the other languages, the library system of JavaScript is not well-equipped. So, developers cannot implement easy tasks using Node.js.
- Since Node.js is asynchronous, the code is not stable and developers have to use nested calls.
In contrast to the pros and cons, Node.js has helped JavaScript by providing it with a backend for complex queries and processing options. Even though JavaScript does not have a resourceful library, using NPM to download libraries and modules is also an added option.
Example Using an Array
The following example is using array and JavaScript memory to fix the heap:
const array = [];
while (true) {
array.push(new Array(10000000));
const memory = process.memoryUsage();
console.log((memory.heapUsed / 1024 / 1024 / 1024).toFixed(4), ‘GB’);
}
Ways to Prevent This Issue
In most cases, increasing the JavaScript memory should do the trick. However, there are times when the system is maxed out and the increasing option is not sufficient. In such a scenario, we can use the following ways to prevent the problem.
– Split Data In Small Groups
Most larger projects are compilations of data, making them huge entries for the system to process. This can be done through MongoDB databases and other types. Furthermore, this procedure is applicable for all the Extract, transform and load (ETL) operations.
Simply put, we will split a file in the number of lines and the number of users.
– Preventing Memory Leakage
If an application keeps showing a JavaScript memory issue, chances are there may be leaks within the memory of that application. If that’s the case, increasing the memory would just be a temporary fix. So, to prevent such mishaps, follow these guidelines:
- We must trace the intervals, timers, variables, and any references that are no longer needed.
- Profiling can help detect such leaks. For frontend, we can profile JavaScript memory by visiting the Memory lab.
- Using Node.js, we can work with Chrome to debug memory usage by running the application in inspection mode. For example, we can use node –inspect index.js.
- We can identify the processes and perform a restart. This is great for machines with limited memory options.
Freeing Memory
We must remember memory cycle is similar for all the programming languages, and it involves these three steps:
- Allocation of the memory
- Using the allocated memory
- Releasing the allocated memory if no longer required
Lastly, let’s discuss the allocation of the JavaScript memory.
– Allocation of the Memory
When the values are declared, JavaScript automatically allocates memory. Here is a way to do it with the following example:
var n = 123;
var s = ‘abc’; //
var o = {
a: 1,
b: null
};
var a = [1, null, ‘abcd’];
function f(a) {
return a + 2;
}
someElement.addEventListener(‘click’, function() {
someElement.style.backgroundColor = ‘blue’;
}, false);
In the example above, we have used numbers, strings, arrays, objects, and functions.
– Using the Memory
Let’s say that we allocated the memory in the example shown above. Once allocated, we can use the value of a variable, object for reading and writing. We can also pass an argument to work accordingly with the function.
– Releasing Memory
When we are ready to release the memory, proper management is a must to avoid a JavaScript issue. Do note this is a crucial step in memory management because finding out the optimum time of release is difficult.
Garbage Collection in JavaScript
For the lower languages, developers have to determine the releasing time. However, for JavaScript (higher language), we use something called “garbage collection”.
Garbage collection uses automatic memory management as mentioned earlier. In simple words, when memory is no longer needed, the system provides an estimated time for release that is not always right as memory might still be in use.
– References in JavaScript Memory Management
By using a garbage collecting model, we can reduce the approximate JavaScript issue of releasing the memory by counting the references. If zero references are pointing towards an object, it is considered garbage and is released.
Moreover, you will find a simple garbage collection method in the example below:
var x = {
a: {
b: 2
}
};
var y = x;
x = 1;
var z = y.a;
y = ‘browser’;
z = null;
In the example shown above, we have references in different numbers pointing at the objects. While some instances have references pointing at each other, the z=null has zero references. Thus, it can be garbage-collected.
Final Thoughts
In the article, we discussed the basics of the JavaScript issue of memory and the methods to free some space, either by increasing or through other procedures. Let’s quickly glance at the summarizing points from this guide:
- The usage of Node.js helps JavaScript provide the backend functionality
- Normally, an increase in memory should be fine unless there is a memory leak
- If there is a memory leak, we have provided a direct guide on how to deal with it above
- To prevent inaccurate estimation by garbage collection method, references are counted to release memory at the right time.
By now, you should have an ample understanding of JavaScript heap size. Still, don’t worry if you don’t get it yet, as you can come back here and use the practice coding examples any time.
- Author
- Recent Posts
Position Is Everything: Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL.