Node.js捕获生成后引发的ENOMEM错误


82

使用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错误?

谢谢!


您是否有示例图片可用于复制问题?
mscdex14年

当服务器内存不足并且无法使用特定图像进行复制时,就会发生这种情况。这很难测试:-/
tobi

您在error处理程序内部正在做什么?
mscdex

1
您找到解决此问题的方法了吗?
sffc 2015年

2
我认为这是使用fork()(基础syscall)的根本缺陷。见github.com/nodejs/node/issues/25382
ZachB

Answers:


201

我遇到了同样的问题,事实证明,我的系统没有启用交换空间。通过运行以下命令检查是否存在这种情况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 GB的交换文件
  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!)

14
只是给以后阅读此答案的任何人的注释。交换文件在重新启动后并不持久。要使其持久化,您需要编辑/ etc / fstab文件并在末尾添加一行:/ swapfile none swap sw 0 0
bman

仅仅给我愚蠢的VM 2个演出就解决了上述问题。
Thomson Comer

2
在生产服务器上这是个好主意吗?我的理解是,当操作系统开始使用交换内存时,性能可能会急剧下降,因此最好为服务器配置足够的RAM来满足应用程序的需求,并积极地追查内存泄漏。
josh

2
@josh,当RAM用完时,将发生以下两种情况之一-内存将被分页到交换文件,或者任何对额外内存的请求都将失败,并出现意外结果。是的,当使用交换文件时,性能可能会下降,但是我会比其他选择花费更多的时间,尤其是在生产环境中。
Kaivosukeltaja

我没有将内存加倍,需要调整大小吗?我该怎么做呢?
杰克


2

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

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

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

如果您的平台的可用内存少于500 mb,请尝试将内存使用率设置为--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) { ... }); 


-5

您必须刷新被调用进程的输出!

python示例如下所示:

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

它不是python
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.