为什么“readFile”使用的内存比读取文件的内容长度多?

时间:2015-02-25 11:22:22

标签: javascript node.js v8

我有一个包含大约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

没有内存消耗(泄漏)。

为什么会这样?

1 个答案:

答案 0 :(得分:2)

  

为什么&#34; readFile&#34;使用比读取文件的内容长度更多的内存?

根据ECMAscript规范,Javascript字符串在内部以UTF-16或UCS-2表示,两者都需要最少的字节来表示每个字符&#34;在文件中。当您将其作为Javascript字符串加载到内存中时,大多数由ASCII字符组成的文本文件的大小可能会大致翻倍。

这与您是否有内存泄漏证据的问题是正交的。

(我会说你没有泄漏的证据。为了证明泄漏的存在,你需要静态来显示堆积大小在多个垃圾收集周期中向上趋势。你只是报告显示差异在堆使用中,在加载文件之前和之后。)