jsdom和node.js泄漏内存

Pet*_*ter 12 memory-leaks node.js jsdom

我找到了一些提到类似问题的人的答案总是如此,确保你在完成后调用window.close().然而,这对我来说似乎没有用(节点0.8.14和jsdom 0.3.1)

一个简单的复制品

var util = require('util');
var jsdom=require('jsdom');

function doOne() {
  var htmlDoc = '<html><head></head><body id="' + i + '"></body></html>';
  jsdom.env(htmlDoc, null, null, function(errors, window) {
    window.close();
  });
}

for (var i=1;i< 100000;i++ )  {
  doOne();
  if(i % 500 == 0)  {
    console.log(i + ":" + util.inspect(process.memoryUsage()));
  }
}
console.log ("done");
Run Code Online (Sandbox Code Playgroud)

我得到的输出是

500:{ rss: 108847104, heapTotal: 115979520, heapUsed: 102696768 }
1000:{ rss: 198250496, heapTotal: 194394624, heapUsed: 190892120 }
1500:{ rss: 267304960, heapTotal: 254246912, heapUsed: 223847712 }
...
11000:{ rss: 1565204480, heapTotal: 1593723904, heapUsed: 1466889432 }
Run Code Online (Sandbox Code Playgroud)

在这一点上,风扇变得疯狂,测试实际上停止了......或者至少开始非常缓慢

有没有人有任何其他提示而不是w​​indow.close摆脱内存泄漏(或者它确实看起来像内存泄漏)

谢谢!

彼得

Che*_*aks 11

使用jsdom 0.6.0来帮助刮掉一些数据并遇到同样的问题.
window.close只是帮助减缓了内存泄漏,但它确实最终爬升直到进程被杀死.

使用运行脚本 node --expose-gc myscript.js

直到他们修复内存泄漏,除了调用之外手动调用垃圾收集器window.close似乎工作:

if (process.memoryUsage().heapUsed > 200000000) { // memory use is above 200MB
    global.gc();
}
Run Code Online (Sandbox Code Playgroud)

在调用window.close后被困住了.每次触发时,内存使用会立即回落到基线(对我来说大约50MB).几乎感觉不到停止.

  • 就我而言,我还必须在 `global.gc()` 之后添加 500 毫秒的睡眠,以使其真正释放内存:`await new Promise(resolve =&gt; setTimeout(resolve, 500));` (2认同)

Dom*_*nic 6

您没有给程序任何空闲时间来进行垃圾收集。我相信您会遇到在循环中紧密创建多次的任何大型对象图而没有中断的相同问题。

这由CheapSteaks的回答证实,它手动强制垃圾收集。如果可行,jsdom 中就不会出现内存泄漏,因为内存泄漏的定义会阻止垃圾收集器收集泄漏的内存。


BeM*_*com 4

我在使用 jsdom 时遇到了同样的问题,并切换到了Cheerio,它比 jsdom 快得多,甚至在扫描了数百个站点后也能正常工作。也许你也应该尝试一下。唯一的问题是,它没有您可以在 jsdom 中使用的所有选择器。

希望它也适合你。

丹尼尔