我有一个包含大约300.000个日志文件的路径。 当我使用" readFile"读取所有这些文件时,我注意到内存消耗(泄漏)方法
以下是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;
(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);
}
}
我得到了以下结果:
Memory usage before files read: 22.45 MB
Memory usage after files read: 437.80 MB
Total files size: 258.19 MB
(437.80 - 22.45)/ 258.19 = 1.6(使用的内存超过了读取文件的内容长度)
但如果我使用&#34; readFileSync&#34;方法我没有注意到内存消耗(泄漏)。
以下是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');
我得到了以下结果:
Memory usage before files read: 22.45 MB
Memory usage after files read: 23.31 MB
Total files size: 258.19 MB
没有内存消耗(泄漏)。
为什么会这样?
答案 0 :(得分:2)
为什么&#34; readFile&#34;使用比读取文件的内容长度更多的内存?
根据ECMAscript规范,Javascript字符串在内部以UTF-16或UCS-2表示,两者都需要最少的字节来表示每个字符&#34;在文件中。当您将其作为Javascript字符串加载到内存中时,大多数由ASCII字符组成的文本文件的大小可能会大致翻倍。
这与您是否有内存泄漏证据的问题是正交的。
(我会说你没有泄漏的证据。为了证明泄漏的存在,你需要静态来显示堆积大小在多个垃圾收集周期中向上趋势。你只是报告显示差异在堆使用中,在加载文件之前和之后。)