Помилка Node.js ловить ENOMEM, викинута після ікру


84

Мій сценарій Node.js аварійно завершує роботу через викинутий ENOMEM (не вистачає пам’яті) errnoException під час використання spawn .

Помилка:

child_process.js:935
  throw errnoException(process._errno, 'spawn');
        ^

Error: spawn ENOMEM
  at errnoException (child_process.js:988:11)
  at ChildProcess.spawn (child_process.js:935:11)
  at Object.exports.spawn (child_process.js:723:9)
  at module.exports ([...]/node_modules/zbarimg/index.js:19:23)

Я вже використовую прослуховувачі для події errorand exit, але жоден з них не звільняється в разі цієї помилки.

Мій код:

zbarimg = process.spawn('zbarimg', [photo, '-q']);
zbarimg.on('error', function(err) { ... });
zbarimg.on('close', function(code) { ... }); 

Доступний повний вихідний код .

Чи можу я щось зробити, щоб запобігти збою сценарію? Як виявити викинуту помилку ENOMEM?

Дякую!


У вас є приклад зображення, за допомогою якого можна відтворити проблему?
mscdex

Це трапляється, коли на сервері не вистачає пам'яті, і його не вдається відтворити з певним зображенням. Це ускладнює тестування: - /
tobi

Що ви робите всередині errorобробника?
mscdex

1
Ви знайшли рішення цієї проблеми?
sffc

2
Я думаю, що це фундаментальний недолік використання fork()(основного syscall). Дивіться github.com/nodejs/node/issues/25382
ZachB

Відповіді:


204

У мене була та сама проблема, і, як виявилося, у моїй системі не було включено обмінний простір . Перевірте, чи це так, запустивши команду free -m:

vagrant@vagrant-ubuntu-trusty-64:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          2002        233       1769          0         24         91
-/+ buffers/cache:        116       1885
Swap:            0          0          0

Дивлячись на нижній рядок, ми бачимо, що загалом у нас є 0 байт пам’яті під обмін. Не добре. Вузол може відчути ситну пам’ять, і якщо місця пам’яті не буде доступно, коли пам’ять закінчиться, помилки обов’язково трапляються.

Метод додавання файлу підкачки різниться між операційними системами та дистрибутивами, але якщо ви використовуєте Ubuntu, як я, ви можете слідувати цим інструкціям щодо додавання файлу підкачки :

  1. sudo fallocate -l 4G /swapfile Створіть 4-гігабайтний файл підкачки
  2. sudo chmod 600 /swapfile Захистіть файл підкачки, обмеживши доступ до root
  3. sudo mkswap /swapfile Позначте файл як простір підкачки
  4. sudo swapon /swapfile Увімкніть обмін
  5. echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstabЗберегти файл підкачки під час перезавантаження (дякую за підказку, bman !)

15
Просто примітка для тих, хто в майбутньому читатиме цю відповідь. Файл підкачки не зберігається при перезавантаженні. Щоб зробити його постійним, вам потрібно відредагувати файл / etc / fstab і додати рядок в кінці: / swapfile none swap sw 0 0
bman

Просто надання моєї дурної ВМ ще 2 концерти оперативної пам'яті вирішило мою вищезазначену проблему.
Томсон Комер,

2
Це хороша ідея на виробничому сервері? Я розумію, що коли ОС починає використовувати обмін пам’яттю, продуктивність може різко погіршитися, тому краще розмірити ваш сервер з достатньою кількістю оперативної пам’яті, щоб задовольнити потреби програм, і агресивно подолати витоки пам'яті.
Джош

2
@josh, коли оперативна пам’ять закінчиться, відбудеться одна з двох речей - або пам’ять потрапить на сторінку до файлу підкачки, або будь-які запити на додаткову пам’ять не спрацюють із несподіваними результатами. Так, продуктивність може погіршитися, коли використовується файл підкачки, але я прийму це в будь-який день за інший варіант, особливо у виробництві.
Кайвосукелтая,

Я не зробив подвійну пам’ять і мені потрібно змінити розмір? Як це зробити?
Джек

5

Якщо ви коли-небудь стикалися з цією проблемою в AWS Lambda, вам слід подумати про збільшення пам’яті, виділеної функції.


2

Ви можете спробувати змінити обсяг використовуваного вузлом пам'яті за допомогою цієї команди: node ----max-old-space-size=1024 yourscript.js

--max-old-space-size = 1024 виділить 1 гіг пам'яті.

За замовчуванням вузол буде використовувати 512 Мб оперативної пам'яті, але, залежно від вашої платформи, вам може знадобитися виділити більш-менш так, щоб збір сміття розпочався тоді, коли вам це потрібно.

Якщо на вашій платформі доступно менше 500 Мб оперативної пам’яті, спробуйте встановити менше використання пам’яті на --max-old-space-size = 256.


1

У мене була та ж проблема та виправлена ​​за допомогою try / catch:

try {
  zbarimg = process.spawn('zbarimg', [photo, '-q']);
} catch (err) {
  console.log(err);
}
zbarimg.on('error', function(err) { ... });
zbarimg.on('close', function(code) { ... }); 

0

Я вирішив проблему, просто вимкнувши та знову ввімкнувши мій Node Server.


-6

Ви повинні очистити результати викликуваного процесу!

Приклад python виглядає так:

import sys
...
sys.stdout.flush()

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