【问题标题】:Node.js catch ENOMEM error thrown after spawnNode.js 捕获生成后引发的 ENOMEM 错误
【发布时间】:2014-11-29 09:07:23
【问题描述】:

我的 Node.js 脚本在使用 spawn 时由于抛出 ENOMEM(内存不足)errnoException 而崩溃。

错误:

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)

我已经在为errorexit 事件使用侦听器,但如果出现此错误,它们都不会被触发。

我的代码:

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

完整源代码available.

我可以做些什么来防止脚本崩溃?如何捕获抛出的 ENOMEM 错误?

【问题讨论】:

  • 您有可用于复制问题的示例图像吗?
  • 当服务器内存不足并且无法使用特定图像复制时会发生这种情况。这使得测试变得困难:-/
  • 你在error处理程序中做什么?
  • 你找到解决这个问题的方法了吗?
  • 我认为这是使用fork()(底层系统调用)的根本缺陷。见github.com/nodejs/node/issues/25382

标签: javascript node.js error-handling try-catch spawn


【解决方案1】:

这解决了我的问题:)

内存问题

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,结果我的系统没有启用交换空间。通过运行命令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 字节的交换内存。不好。 Node 可能会占用大量内存,如果内存耗尽时没有可用的交换空间,则必然会发生错误。

        添加交换文件的方法因操作系统和发行版而异,但如果你像我一样运行 Ubuntu,你可以关注这些instructions on adding a swap file

        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!)

        【讨论】:

        • 只是给将来阅读此答案的任何人的注释。交换文件在重新启动时不持久。要使其持久化,您需要编辑 /etc/fstab 文件并在末尾添加一行:/swapfile none swap sw 0 0
        • 只要再给我愚蠢的虚拟机 2 个 ram 演出就解决了我的上述问题。
        • 在生产服务器上这是个好主意吗?我的理解是,当操作系统开始使用交换内存时,性能会急剧下降,因此最好为服务器设置足够的 RAM 来满足应用程序的需求,并积极寻找内存泄漏。
        • @josh,当 RAM 用完时,会发生以下两种情况之一 - 内存将被分页到交换文件,或者任何额外内存的请求都将失败并导致意外结果。是的,使用交换文件时性能可能会下降,但我会在任何一天都采用其他选项,尤其是在生产中。
        • 经过大量搜索后,我只需要这个答案(并教我交换内存)。强烈建议将此作为答案
        【解决方案5】:

        我也遇到了同样的问题,用 try / catch 解决了:

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

        【讨论】:

          【解决方案6】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-10-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-12
            • 2022-01-25
            • 1970-01-01
            相关资源
            最近更新 更多