文件上传完成后,node.js内存不足

时间:2019-04-12 12:21:15

标签: node.js express out-of-memory child-process busboy

enter image description here我有一个运行在armv7 SBC(具有128MB RAM的Atmel SAMA5D27-SOM)上的嵌入式Linux上的Web服务器。

固件更新过程要求通过该接口上传.tar.gz文件,然后解压缩/解压缩并在其上运行进一步的过程。

使用busboy模块成功上传后,我注意到即使将上传直接流式传输到文件中(以下代码),内存使用率仍然很高(请参见附件图像)。

文件上传后,使用child_processes实现的其他进程由于系统内存不足而被杀死。

我已经将--max-old-size-space-size标志实现为= 32MB,因为我已经读到这为GC启动时设置了一个较低的阈值。

我尝试了各种使用child_processes API的方法,包括: 1. execSync 2.异步执行(如node.js文档中所述) 3.使用{detached:true}

生成
/* imports omitted for brevity */

module.exports = async (req, res, next) => { // eslint-disable-line no-unused-vars
  try {

    /* File validation omitted for brevity */

    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
      /* Further file validation omitted for brevity,
         File transfer debugging omitted for brevity */


      // Handle saving file stream to file
      const saveTo = path.join(updatesDir, path.basename(filename));
      file.pipe(fs.createWriteStream(saveTo));
    });

    busboy.on('finish', () => {
      return res.json({ updateFilename });
    });

    // This is required stream req progress back to browser
    return req.pipe(busboy);
  } catch (error) {
    console.error(error)
    next(error);
  }
}

我了解到node.js使用了垃圾回收器,但是文件上传所占用的内存并未释放供以后的进程使用。

我将文件上传流传输到文件的方式有问题吗? 为什么Node.js不释放内存? 在这种情况下是否可以手动触发GC?

1 个答案:

答案 0 :(得分:1)

进一步的测试表明,嵌入式Linux系统默认不包含交换内存。我创建了一个交换文件,并使其大小与系统RAM(128MB)相同。后来,由于SD卡上有额外的可用空间,我增加了此开销以提供额外的开销。

这允许linux通过将非关键内存使用情况移动到光盘上来自动管理OOM问题。此过程确实使上传速度降低了几秒钟,但确实阻止了所有OOM内存问题。