[英]node.js - require error causes memory leak?
I have the following program which grows its heap continuously. 我有以下程序会不断增加其堆。 It's a very simple program which repeatedly loads an external file ( SyntaxError
) via require
. 这是一个非常简单的程序,可以通过require
反复加载外部文件( SyntaxError
)。 The external module fails to load because of a syntax error in it. 外部模块由于语法错误而无法加载。
I run the node garbage collector and dump heap size to see if memory is leaking. 我运行节点垃圾收集器并转储堆大小,以查看内存是否泄漏。 If I fix the syntax error in the external file ( SyntaxError.js
), then the leak goes away and memory usage remains constant after a million iterations. 如果我在外部文件( SyntaxError.js
)中修复了语法错误,则泄漏消失了,在一百万次迭代后内存使用率保持不变。
Using node version: 0.10.29 with --expose-gc
使用节点版本:0.10.29和--expose-gc
Any insights into what might be happening and how I can avoid mem leak would be greatly appreciated. 对于可能发生的事情以及如何避免内存泄漏的任何见解,将不胜感激。
Test code: 测试代码:
(function() {
var MAX_ITER_COUNT, MEGABYTE, dumpMem, gc, iterCount, noop, peakMem, test2;
iterCount = 0;
MAX_ITER_COUNT = 1000 * 1000;
peakMem = 0;
MEGABYTE = 1024 * 1024;
noop = function() {};
dumpMem = function() {
var currentMem;
currentMem = Math.round(process.memoryUsage().heapUsed / MEGABYTE);
if (currentMem > peakMem) {
peakMem = currentMem;
}
return console.log("" + iterCount + " - memory is: " + currentMem + "/" + peakMem + " MB");
};
gc = function() {
return global.gc();
};
process.on("uncaughtException", function(err) {
return console.log("Unhandled exception! ", err, err.stack);
});
test2 = function() {
var e;
iterCount++;
try {
/*
Load a module that has a syntax error to create mem leak, and ignore exception
*/
require("./SyntaxError");
} catch (_error) {
e = _error;
}
gc();
dumpMem();
return setTimeout(test2, 0);
};
test2();
}).call(this);
And SyntaxError.js: 和SyntaxError.js:
(function() {
'use strict';
/* y does not exist, and results in exception*/
var x;
x = y;
}).call(this);
Seems like this is a node bug. 似乎这是一个节点错误。 I could work around it by putting the try/catch around the body of SyntaxError.js inside SyntaxError.js. 我可以通过将try / catch放在SyntaxError.js 内的 SyntaxError.js主体周围来解决此问题。 My test, simplified from the above: 我的测试,从上面简化:
mem-leak-bug.js: MEM-泄漏bug.js:
for (i=0; i<1000000; i++) {
try {
require('./mem-leak--error.js');
}
catch (e) { }
if (i % 1000 === 0) {
global.gc();
console.log(i, process.memoryUsage().heapUsed/1e6|0, process.memoryUsage().heapTotal/1e6|0);
}
}
mem-leak--error.js: MEM泄漏 - error.js:
NOTE: there must be an explicit return in the catch block, else this too leaks memory 注意:catch块中必须有一个明确的返回值,否则这也会泄漏内存
// throw an undefined variable exception
try {
return x;
}
catch(e) {
return;
}
Without the try-catch, it leaks memory: 没有try-catch,它将泄漏内存:
% node --expose-gc ar/mem-leak-bug.js
0 1 5
1000 2 14
2000 2 14
3000 3 14
4000 3 23
5000 3 23
6000 4 24
With the try-catch inside SytaxError, it doesn't: 使用SytaxError内部的try-catch,它不会:
% node --expose-gc ar/mem-leak-bug.js
0 1 5
1000 1 7
2000 1 7
3000 1 7
4000 1 7
5000 1 7
6000 1 7
7000 1 7
8000 1 7
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.