Node.js накопичується з пам'яті


247

Сьогодні я запустив свій скрипт для індексації файлової системи, щоб оновити індекс файлів RAID, і через 4 години він вийшов з ладу із наступною помилкою:

[md5:]  241613/241627 97.5%  
[md5:]  241614/241627 97.5%  
[md5:]  241625/241627 98.1%
Creating missing list... (79570 files missing)
Creating new files list... (241627 new files)

<--- Last few GCs --->

11629672 ms: Mark-sweep 1174.6 (1426.5) -> 1172.4 (1418.3) MB, 659.9 / 0 ms [allocation failure] [GC in old space requested].
11630371 ms: Mark-sweep 1172.4 (1418.3) -> 1172.4 (1411.3) MB, 698.9 / 0 ms [allocation failure] [GC in old space requested].
11631105 ms: Mark-sweep 1172.4 (1411.3) -> 1172.4 (1389.3) MB, 733.5 / 0 ms [last resort gc].
11631778 ms: Mark-sweep 1172.4 (1389.3) -> 1172.4 (1368.3) MB, 673.6 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3d1d329c9e59 <JS Object>
1: SparseJoinWithSeparatorJS(aka SparseJoinWithSeparatorJS) [native array.js:~84] [pc=0x3629ef689ad0] (this=0x3d1d32904189 <undefined>,w=0x2b690ce91071 <JS Array[241627]>,L=241627,M=0x3d1d329b4a11 <JS Function ConvertToString (SharedFunctionInfo 0x3d1d3294ef79)>,N=0x7c953bf4d49 <String[4]\: ,\n  >)
2: Join(aka Join) [native array.js:143] [pc=0x3629ef616696] (this=0x3d1d32904189 <undefin...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/bin/node]
 2: 0xe2c5fc [/usr/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/bin/node]
 6: v8::internal::Runtime_SparseJoinWithSeparator(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
 7: 0x3629ef50961b

Сервер оснащений 16 Гб оперативної пам’яті та 24gb SSD свопом. Я дуже сумніваюся, що мій сценарій перевищив 36 Гб пам'яті. Принаймні, це не повинно

Сценарій створює індекс файлів, що зберігаються як масив об'єктів з метаданими файлів (дати модифікації, дозволи тощо, відсутні великі дані)

Ось повний код сценарію: http://pastebin.com/mjaD76c3

Я вже очікував дивних проблем із вузлами в минулому з цим сценарієм, що змусило мене, наприклад. розділити індекс на кілька файлів, оскільки вузол виблискував під час роботи над такими великими файлами, як String. Чи є спосіб поліпшити управління пам'яттю nodejs за допомогою величезних наборів даних?

Відповіді:


315

Якщо я правильно пам’ятаю, існує суворий стандартний ліміт використання пам'яті у V8 близько 1,7 ГБ, якщо ви не збільшуєте його вручну.

В одному з наших продуктів ми дотримувались цього рішення в нашому сценарії розгортання:

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

Була б також нова команда пробілу, але, як я прочитав тут: a-tour-of-v8-garbage-collection, новий простір збирає лише щойно створені короткострокові дані, а старий простір містить усі посилання на структуру даних, які повинні бути в ваш випадок найкращий варіант.


Таким же чином цей конфігуратор призначений для nodejs незалежно від фреймворку. @ Simer
— Felix

Я розробляю з кутовим 4 і отримую те саме питання, яким має бути файл yourFile.js для кутового додатка?
— Vikram

@VikramSingh використовуєте ви ng serveчи розповсюджуєте результат ng buildпапки / dist іншим веб-сервером, як express? Але якщо ваш проект Angular використовує більше стандартної пам'яті 1,7 Гб, ніж можливо, у вашій програмі виникне архітектурна проблема? Схоже, ви використовуєте розробку env з nmp start, можливо, це рішення для неї github.com/mgechev/angular-seed/isissue/2063
— Фелікс

Я використовую ng build з кутовим cli та aot (dist папка)
— Vikram

2
індекс, JS файл @Techdive , який використовується для запуску сервера
— Basit

77

На всякий випадок, якщо хтось стикається з цим у середовищі, де він не може встановити властивості вузла безпосередньо (у моєму випадку інструмент збірки):

NODE_OPTIONS="--max-old-space-size=4096" node ...

Ви можете встановити параметри вузлів за допомогою змінної середовища, якщо ви не можете передати їх у командному рядку.


Чи можете ви пояснити, що ви маєте на увазі, коли ви говорите "... встановити параметри вузла за допомогою змінної середовища ..."?
— Кезельме

6
@Keselme Змінна середовища - це змінна, встановлена ​​на сервері, з якої всі процеси можуть читати дані. Відкрийте на своєму сервері термінал SSH та введіть: MY_VAR = привіт, а потім наберіть: echo $ MY_VAR. Ви побачите, що він друкує "привіт" в терміналі. Ви просто встановили змінну середовища та прочитали її назад.
— Роб Еванс

працював над Ubuntu 18.04, щойно додав команду експорту до мого файлу
— Рахал Канішка

76

Якщо ви хочете збільшити використання пам'яті вузла в усьому світі - не лише один сценарій, ви можете експортувати змінну середовища, наприклад, таким:
export NODE_OPTIONS=--max_old_space_size=4096

Тоді вам не потрібно грати з файлами при виконанні таких збірок npm run build.


1
Як додаткову зручність додайте до bash_profile або zsh-профіль.
— Tropicalrambler

24

Я зіткнувся з цією проблемою під час спроби налагодження з VSCode, тому просто хотів додати. Це те, як ви можете додати аргумент у налаштування налагодження.

Ви можете додати його у runtimeArgsвластивість конфігурації в launch.json.

Дивіться приклад нижче.

{
"version": "0.2.0",
"configurations": [{
        "type": "node",
        "request": "launch",
        "name": "Launch Program",
        "program": "${workspaceRoot}\\server.js"
    },
    {
        "type": "node",
        "request": "launch",
        "name": "Launch Training Script",
        "program": "${workspaceRoot}\\training-script.js",
        "runtimeArgs": [
            "--max-old-space-size=4096"
        ]
    }
]}

21

Ось деякі значення прапорця, щоб додати додаткову інформацію про те, як додати більше пам’яті при запуску сервера вузлів.

1 ГБ - 8 ГБ

#increase to 1gb
node --max-old-space-size=1024 index.js

#increase to 2gb
node --max-old-space-size=2048 index.js 

#increase to 3gb
node --max-old-space-size=3072 index.js

#increase to 4gb
node --max-old-space-size=4096 index.js

#increase to 5gb
node --max-old-space-size=5120 index.js

#increase to 6gb
node --max-old-space-size=6144 index.js

#increase to 7gb
node --max-old-space-size=7168 index.js

#increase to 8gb 
node --max-old-space-size=8192 index.js 

чи можна продовжувати збільшувати його в потужностях 2? чи варто встановити його більше, ніж системна пам'ять? якщо ні, то яка хороша системна пам'ять відношення макс-старе-простір-розмір?
— Гаррі Морено

3
@HarryMoreno Ви можете фактично ввести будь-яке число, яке вам подобається. Не повинно бути потужністю 2. Хоча не впевнений у співвідношенні. Це лише максимальна межа, вона не буде використовувати всю пам'ять. Я б просто встановив його так високо, як вам потрібно, а потім при необхідності масштабувати назад.
— Ніколас Портер

Я дам системний таран - 1 Гб спробувати. Припустимо, що цей vm призначений лише для запуску цього вузла.
— Гаррі Морено

2
@HarryMoreno Хороший системний об'єм пам’яті до максимального старого-розмір простору залежить повністю від того, що ще працює на вашій машині. Ви можете збільшити його в двох потужностях - або можете використовувати будь-яке число. Ви можете встановити його більше, ніж системна пам’ять - але ви будете стикатися з питаннями свопу.
— Gigimoi

20

я боровся з цим навіть після встановлення - max-old-space-size.

Тоді я зрозумів, що потрібно поставити параметри - max-old-space-size перед карма-скриптом.

також найкраще вказати обидва синтаксиси - max-old-space-size та --max_old_space_size мій сценарій карми:

node --max-old-space-size=8192 --optimize-for-size --max-executable-size=8192  --max_old_space_size=8192 --optimize_for_size --max_executable_size=8192 node_modules/karma/bin/karma start --single-run --max_new_space_size=8192   --prod --aot

посилання https://github.com/angular/angular-cli/isissue/1652


5
" найкраще вказати обидва синтаксиси - max-old-space-size та --max_old_space_size " - вам цього не потрібно, вони є синонімами. Від nodejs.org/api/cli.html#cli_options : "Усі параметри, включаючи параметри V8, дозволяють розділяти слова двома тире (-) або підкресленнями (_)."
— ZachB

6
max-исполняемый розмір був видалений і закінчується помилкою при його використанні: github.com/nodejs/node/issues/13341
— аварійний рух

Мені довелося скоротити, --max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizeі це спрацювало
— Сергій Плешаков

16

У мене була подібна проблема під час виконання AOT кутового складання. Наступні команди мені допомогли.

npm install -g increase-memory-limit
increase-memory-limit

Джерело: https://geeklearning.io/angular-aot-webpack-memory-trick/


1
Ура працювали на мене, можливо, знадобитьсяsudo npm -g install increase-memory-limit --unsafe-perm
— Лев

11

fwiw, знаходження та виправлення свиней пам’яті чимось на зразок memwatch може допомогти.


10

Кроки щодо вирішення цієї проблеми (у Windows) -

  1. Відкрийте командний рядок і введіть %appdata%клавішу Enter
  2. Перейдіть до %appdata%папки> npm
  3. Відкрити або відредагувати ng.cmd у своєму улюбленому редакторі
  4. Додайте --max_old_space_size=8192до блоку IF та ELSE

Ваш node.cmdфайл виглядає приблизно так після зміни:

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe" "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
)

Це специфічно для Windows. ОП нічого не згадувало про Windows.
— Дан Даскалеску

@DanDascalescu Оновлений відповідь. Дякуємо за повідомлення
— Umang Patwa

6

Можна використовувати наступну змінну середовища:

NODE_OPTIONS= --max-old-space-size=8192 .

Ще одна примітка: console.log()також споживає пам'ять в терміналі.

просто спробував прокоментувати console.log () на терміналі. тому що це також займе пам'ять.


6
Це відповідь чи коментар до якоїсь відповіді? Є багато відповідей зNODE_OPTIONS= --max-old-space-size=somesize
— barbsan

5

якщо ви хочете глобально змінити пам'ять для вузла (windows), перейдіть до розширених системних налаштувань -> змінні середовища -> нова змінна користувача

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096

4

Я спробував code код нижче та його добре працює✌.

  • відкрити термінал від кореневого редактора проекту
  • виконати cmd для встановлення нового розміру.

    set NODE_OPTIONS=--max_old_space_size=8172

Або ви можете перевірити посилання для отримання додаткової інформації https://github.com/nodejs/node/isissue/10137#issuecomment-487255987


4

Я просто хочу додати, що в деяких системах, навіть збільшення межі пам’яті вузла --max-old-space-size, недостатньо, і є помилка ОС на зразок цієї:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

У цьому випадку, ймовірно, це тому, що ви досягли максимальної mmap за процес.

Ви можете перевірити max_map_count, запустивши

sysctl vm.max_map_count

і збільшує його, запускаючи

sysctl -w vm.max_map_count=655300

і виправте його, щоб він не був скинутий після перезавантаження, додавши цей рядок

vm.max_map_count=655300

у /etc/sysctl.confфайл.

Перегляньте тут для отримання додаткової інформації.

Хорошим методом аналізу помилки є запуск процесу з strace

strace node --max-old-space-size=128000 my_memory_consuming_process.js

3

Нещодавно я зіткнувся з цією самою проблемою і натрапив на цю тему, але моя проблема була в Reactдодатку. Нижче зміни в команді запуск вузла вирішили мої проблеми.

Синтаксис

node --max-old-space-size=<size> path-to/fileName.js

Приклад

node --max-old-space-size=16000 scripts/build.js

Чому розмір становить 16000 у максимальному розмірі старого простору?

По суті, він змінюється, залежить від виділеної пам'яті для цього потоку та налаштувань вашого вузла.

Як перевірити і надати потрібний розмір?

Це в основному залишається в нашому двигуні v8. нижче код допоможе вам зрозуміти розмір купи вашого двигуна локального вузла v8.

const v8 = require('v8');
const totalHeapSize = v8.getHeapStatistics().total_available_size;
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
console.log('totalHeapSizeGb: ', totalHeapSizeGb);

2

Я щойно зіткнувся з тією ж проблемою з моїм екземпляром EC2 t2.micro, який має 1 Гб пам'яті.

Я вирішив проблему, створивши файл swap за допомогою цього url та встановивши наступну змінну середовища.

export NODE_OPTIONS=--max_old_space_size=4096

Нарешті проблема пішла.

Я сподіваюся, що це буде корисним для майбутнього.


1

На всякий випадок, якщо це може допомогти людям, які мають цю проблему, під час використання додатків nodejs, що виробляють важкі журнали, колега вирішив цю проблему, передавши стандартний висновок у файл.


1

Якщо ви намагаєтеся запустити не nodeсебе, а якийсь інший софт, наприкладwebpack ви можете використовувати змінну середовища та cross-envпакунок:

$ cross-env NODE_OPTIONS='--max-old-space-size=4096' \
  webpack --progress --config build/webpack.config.dev.js

1

Для кутового згрупування проекту я додав нижчий рядок до мого файлу pakage.json у розділі сценаріїв .

"build-prod": "node --max_old_space_size=5120 ./node_modules/@angular/cli/bin/ng build --prod --base-href /"

Тепер, щоб зв’язати свій код, я використовую npm run build-prod замістьng build --requiredFlagsHere

сподіваюся, що це допомагає!


0

Оновіть вузол до останньої версії. Я був на вузлі 6.6 з цією помилкою та оновив до 8.9.4, і проблема пішла.


0

У моєму випадку я працював npm installна попередній версії вузла, через якийсь день я оновив версію вузла і таран npm installдля декількох модулів. Після цього я отримував цю помилку. Щоб виправити цю проблему, я видалив папку node_module з кожного проекту і запустився npm installзнову.

Сподіваюся, це може виправити проблему.

Примітка. Це відбувалося на моїй локальній машині, і вона фіксувалася лише на локальній машині.


0

Ця команда прекрасно працює. У мене в ноутбуці є 8 ГБ, тому я встановив розмір = 8192. Це все про ram, а також вам потрібно встановити ім'я файлу. Я запускаю команду npm run build , тому я використовував build.js .

node --expose-gc --max-old-space-size=8192 node_modules/react-scripts/scripts/build.js

0

У моєму випадку я оновив версію node.js до останньої, і це спрацювало як шарм.


Привіт Анжела і Ласкаво просимо до SO! Не могли б ви вказати точну версію Node.js, яку ви оновили для майбутніх читачів? Дякую!
— kant312

Я перейшов до останньої версії LTS: 12.18.0
— Анжела Рана
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.