为什么“readFile”方法将文件的内容放入内存与“readFileSync”相反?

这是NodeJS代码(同步版本)的一个例子:

var fs = require('fs'); var path = './parseLogFiles/reports'; var counter = 0; var totalFileSize = 0; var fileName; var fullPath; function toMb (byteVal) { return (byteVal / 1048576).toFixed(2); } var filesList = fs.readdirSync(path); console.log('Memory usage before files read:', toMb(process.memoryUsage()['heapUsed']) + ' MB'); for (var i = 0, len = filesList.length; i < len; i++) { fileName = filesList[i]; if (fileName) { fullPath = path + '/' + fileName; totalFileSize += fs.statSync(fullPath)['size']; try { fs.readFileSync(fullPath, {encoding: 'utf8'}); } catch(err){ console.log('err: ', err); } } } console.log('Memory usage after files read:', toMb(process.memoryUsage()['heapUsed']) + ' MB'); console.log('Total files size:', toMb(totalFileSize) + ' MB'); 

我有以下结果:

文件读取之前的内存使用情况:22.45 MB
文件读取后的内存使用情况:23.31 MB
文件总大小:258.19 MB

这里是asynchronous版本:

 ... for (var i = 0, len = filesList.length; i < len; i++) { fileName = filesList[i]; if (fileName) { fullPath = path + '/' + fileName; (function(fullPath){ fs.stat(fullPath, function(err, stat){ totalFileSize += stat['size']; fs.readFile(fullPath, {encoding: 'utf8'}, function(){ if (++counter === len) { console.log('Memory usage after files read:', toMb(process.memoryUsage()['heapUsed']) + ' MB'); console.log('Total files size:', toMb(totalFileSize) + ' MB'); } }); }); })(fullPath); } } 

我有以下结果:

文件读取之前的内存使用情况:22.45 MB
文件读取后的内存使用情况:437.88 MB
文件总大小:258.19 MB

为什么会发生(23.31 MB vs 437.88 MB)?

在你的同步版本中,数据被垃圾回收,因为你没有把返回值赋给任何东西。 在asynchronous版本中,最终文件不允许被垃圾收集,因为它可以通过arguments访问,即使你没有设置显式参数。

为了certificate这一点,我对单个文件进行了简单的testing。 在基本版本中我得到的结果与你的相似(尽pipe在每次内存使用检查之前我必须强制gc)。 但是,如果我只是从readFileSync的返回中存储数据,则该版本使用的内存几乎与asynchronous内存量相同。

如果你担心内存使用,你应该使用fs.createReadStream 。