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.