最近一个项目 发现有大量的内存泄露。 然后用google 搜到了 这篇 https://github.com/joyent/node/issues/4273 issue
哪位,能解释一下吗?
有什么办法释放SetTimeout 的内存?
这段代码不能说明 “内存泄露”。 这段代码本身有大量的消耗操作。 可近一步优化。
乎略掉 延时执行, 引擎 会将如下递规代码全部展开,然后从最底层执行 clearTimeout(x); … 推段,gc回收并不及时。
for (var i = 0; i < 10000000; i++) { var x = setTimeout(noop, );
没错,gc 确实回收不及时。 node --nouse_idle_notification --expose_gc test.js 但是 用 gobal.gc() 好像会把所有内存都清除了。
node -v0.10.7 正常,node -v0.8.x确实内存增长很快,看了下timer.js的实现,似乎是循环引用导致gc不能直接回收,只能在内存超过阀值后使用其他策略(mark and sweep?)来回收。在测试代码clearTimeout(x)
前后分别加入var list=x._idlePrev
和for(var k in list)list[k]=null
,清掉循环引用后,内存的增长重新变得平稳了。
var noop = function() {};
//setTimeout(noop, 100);
for (var i = 0; i < 10000000; i++) {
var x = setTimeout(noop, 100);
var list=x._idlePrev;
clearTimeout(x);
for(var k in list)list[k]=null;
if (i % 300000 == 0) {
gc();
console.log(i, (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');
}
}
注:这段测试代码只适用于nodev -v0.8.x
版本