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

tob*_*obi 70 javascript error-handling try-catch spawn node.js

由于在使用spawn时抛出了ENOMEM(内存不足)错误,我的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)
Run Code Online (Sandbox Code Playgroud)

我已经在errorexit事件中使用了侦听器,但是如果出现此错误,则不会触发它们.

我的代码:

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

完整源代码可用.

有什么办法可以防止脚本崩溃吗?如何捕获抛出的ENOMEM错误?

谢谢!

Kai*_*aja 175

我遇到了同样的问题,事实证明,我的系统没有启用交换空间.通过运行命令检查是否是这种情况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
Run Code Online (Sandbox Code Playgroud)

查看底行我们可以看到我们总共有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!)

  • 对于将来正在阅读此答案的任何人来说,这只是一个注释.Swapfile在重新启动时不会持久.要使其持久化,您需要编辑/ etc/fstab文件并在末尾添加一行:/ swapfile none swap sw 0 0 (13认同)
  • 这对生产服务器来说是个好主意吗?我的理解是,当操作系统开始使用交换内存时,性能会急剧下降,因此最好使用足够的RAM来调整服务器的大小以处理应用程序的需求,并积极寻找内存泄漏. (2认同)
  • @josh,当RAM用完时,将发生以下两种情况之一-内存将被分页到交换文件,或者任何对额外内存的请求都将失败,并导致意外结果。是的,当使用交换文件时,性能可能会下降,但是我会比其他选择(特别是在生产中)花费更多的时间。 (2认同)

Jam*_*iro 6

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


Dee*_*moe 4

您可以尝试使用以下命令更改内存节点使用量: node ----max-old-space-size=1024 yourscript.js

--max-old-space-size=1024 将分配 1 GB 内存。

默认情况下,节点将使用 512 mb 的 RAM,但根据您的平台,您可能需要分配更多或更少的内存,以便垃圾收集在您需要时启动。

如果您的平台可用 RAM 少于 500 MB,请尝试将内存使用率设置为较低至 --max-old-space-size=256。