我有一个运行在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?
答案 0 :(得分:1)
进一步的测试表明,嵌入式Linux系统默认不包含交换内存。我创建了一个交换文件,并使其大小与系统RAM(128MB)相同。后来,由于SD卡上有额外的可用空间,我增加了此开销以提供额外的开销。
这允许linux通过将非关键内存使用情况移动到光盘上来自动管理OOM问题。此过程确实使上传速度降低了几秒钟,但确实阻止了所有OOM内存问题。