简体   繁体   English

Node.js 捕获生成后抛出的 ENOMEM 错误

[英]Node.js catch ENOMEM error thrown after spawn

My Node.js script crashes because of a thrown ENOMEM (Out of memory) errnoException when using spawn .我的 Node.js 脚本因使用spawn时抛出的 ENOMEM(内存不足)errnoException 而崩溃。

The error:错误:

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)

I'm already using listeners for the error and exit event, but non of them getting fired in case of this error.我已经在使用侦听器来处理errorexit事件,但是在发生此错误的情况下,它们都不会被触发。

My code:我的代码:

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

Full source code available .可用的完整源代码。

Is there anything I can do to prevent the script from crashing?我能做些什么来防止脚本崩溃? How do I catch the thrown ENOMEM error?如何捕获抛出的 ENOMEM 错误?

I had the same problem and as it turned out, my system had no swap space enabled .我遇到了同样的问题,结果证明我的系统没有启用交换空间 Check if this is the case by running the command free -m :通过运行命令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

Looking at the bottom row we can see we have a total of 0 bytes swap memory.查看底行,我们可以看到总共有 0 字节的交换内存。 Not good.不好。 Node can get pretty memory hungry and if no swap space is available when memory runs out, errors are bound to happen. Node 可能会占用大量内存,如果内存耗尽时没有可用的交换空间,则必然会发生错误。

The method for adding a swap file varies between operating systems and distributions, but if you're running Ubuntu like me you can follow these instructions on adding a swap file :添加交换文件的方法因操作系统和发行版而异,但如果您像我一样运行 Ubuntu,则可以按照以下说明添加交换文件

  1. sudo fallocate -l 4G /swapfile Create a 4 gigabyte swapfile sudo fallocate -l 4G /swapfile创建一个 4 GB 的交换文件
  2. sudo chmod 600 /swapfile Secure the swapfile by restricting access to root sudo chmod 600 /swapfile通过限制对 root 的访问来保护交换文件
  3. sudo mkswap /swapfile Mark the file as a swap space sudo mkswap /swapfile将文件标记为交换空间
  4. sudo swapon /swapfile Enable the swap sudo swapon /swapfile启用交换
  5. echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab Persist swapfile over reboots (thanks for the tip, bman !) echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab在重新启动时保持交换文件(感谢您的提示, bman !)

如果您在 AWS Lambda 中遇到过这个问题,您应该考虑增加分配给函数的内存。

You can try changing the amount of memory node uses with this command: node ----max-old-space-size=1024 yourscript.js您可以尝试使用以下命令更改节点使用的内存量: node ----max-old-space-size=1024 yourscript.js

--max-old-space-size=1024 will allocate 1 gig of memory. --max-old-space-size=1024 将分配 1 gig 的内存。

By default node will use 512 mb of ram but depending on your platform you may need to allocate more or less so the garbage collection kicks in when you need it.默认情况下,节点将使用 512 mb 内存,但根据您的平台,您可能需要分配更多或更少的内存,以便在您需要时启动垃圾收集。

If your platform has less than 500 mb of ram available then try setting the memory usage lower to --max-old-space-size=256.如果您的平台可用内存少于 500 mb,请尝试将内存使用量设置为 --max-old-space-size=256。

I've had the same problem and fixed with try / catch:我遇到了同样的问题并通过 try / catch 修复:

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

我通过禁用和重新启用我的节点服务器解决了这个问题。

This solved my problem :)这解决了我的问题:)

The issue with memory内存问题

free -m
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo “/swapfile none swap sw 0 0” | sudo tee -a /etc/fstab

You have to flush the outputs from the called process! 您必须刷新被调用进程的输出!

A python example looks like this: python示例如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM