Node.jsは、スポーン後にスローされたENOMEMエラーをキャッチします


84

spawnを使用すると、ENOMEM(メモリ不足)errnoExceptionがスローされたため、Node.jsスクリプトがクラッシュします

エラー:

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)

私はすでにerrorandexitイベントのリスナーを使用していますが、このエラーが発生した場合にリスナーは起動されません。

私のコード:

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

利用可能な完全なソースコード。

スクリプトがクラッシュするのを防ぐためにできることはありますか?スローされたENOMEMエラーをキャッチするにはどうすればよいですか?

ありがとう!


問題を再現するために使用できるサンプル画像はありますか?
mscdex 2014年

サーバーのメモリが不足していて、特定の画像で再現できない場合に発生します。それはテストを難しくします:-/
tobi 2014年

errorハンドラー内で何をしていますか?
mscdex 2014年

1
この問題の解決策を見つけましたか?
sffc 2015年

2
これはfork()(基礎となるシステムコール)の使用に関する根本的な欠陥だと思います。参照してください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 ルートへのアクセスを制限してスワップファイルを保護します
  3. sudo mkswap /swapfile ファイルをスワップスペースとしてマークする
  4. sudo swapon /swapfile スワップを有効にする
  5. echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab再起動後もswapfileを永続化します(ヒントをありがとうbman!)

15
この答えを読んでいる将来の人へのメモ。Swapfileは再起動時に永続的ではありません。永続的にするには、/ etc / fstabファイルを編集し、最後に行を追加する必要があります
。/swapfile

愚かなVMにRAMを2ギガ追加するだけで、上記の問題は解決しました。
トムソンカマー2017年

2
これは本番サーバーでは良い考えですか?私の理解では、OSがスワップメモリ​​の使用を開始すると、パフォーマンスが大幅に低下する可能性があるため、アプリケーションのニーズを処理するのに十分なRAMを備えたサーバーのサイズを設定し、メモリリークを積極的に回避することをお勧めします。
josh 2017

2
@ josh、RAMがなくなると、次の2つのいずれかが発生します。メモリがスワップファイルにページングされるか、追加メモリの要求が失敗して予期しない結果が発生します。はい、スワップファイルを使用するとパフォーマンスが低下する可能性がありますが、特に本番環境では、他のオプションよりもいつでもそれを利用します。
Kaivosukeltaja 2017年

メモリを2倍にしなかったので、サイズを変更する必要がありますか?どうすればよいですか?
ジャック


2

次のコマンドを使用して、ノードが使用するメモリの量を変更してみてください。 node ----max-old-space-size=1024 yourscript.js

--max-old-space-size = 1024は、1ギガのメモリを割り当てます。

デフォルトでは、ノードは512 mbのRAMを使用しますが、プラットフォームによっては、必要なときにガベージコレクションが開始されるように、多かれ少なかれ割り当てる必要がある場合があります。

プラットフォームで使用可能なRAMが500MB未満の場合は、メモリ使用量を--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()

Pythonではありません
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.