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

node.js out of memory after file upload complete

我有一个网络服务器 运行ning 在嵌入式 linux 运行ning 上,在 armv7 SBC(具有 128MB RAM 的 Atmel SAMA5D27-SOM)上。

固件更新过程需要通过此接口上传.tar.gz文件,然后untarred/unzipped并进一步处理运行。

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

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

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

我尝试了多种使用 child_processes API 的方法,包括: 1.执行同步 2. async exec(如 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?

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

这允许 linux 通过将 non-critical 内存使用转移到磁盘上来自动管理 OOM 问题。此过程确实使上传速度减慢了几秒钟,但它确实阻止了所有 OOM 内存问题。