首页 > 解决方案 > 文件上传完成后node.js内存不足

问题描述

在此处输入图像描述我有一个在 armv7 SBC(Atmel SAMA5D27-SOM 和 128MB RAM)上运行的嵌入式 linux 上运行的 Web 服务器。

固件更新过程需要通过此界面上传 .tar.gz 文件,然后解压缩/解压缩并在其上运行进一步的过程。

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

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

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

我尝试了各种使用 child_processes API 的方法,包括:1. execSync 2. async exec(如 node.js 文档中所述) 3. spawn with {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?

标签: node.jsexpressout-of-memorychild-processbusboy

解决方案


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

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


推荐阅读