jsdom和node.js内存泄漏

jsdom和node.js内存泄漏,node.js,memory-leaks,jsdom,Node.js,Memory Leaks,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&g

我发现一些人也有类似的问题,答案总是,确保完成后调用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");
在这一点上,风扇变得疯狂,测试实际上停止了……或者至少开始非常缓慢地进行

除了window.close之外,还有谁有其他的提示来消除内存泄漏(或者看起来确实像内存泄漏)

谢谢


Peter

我对jsdom和switcht to也有同样的问题,它比jsdom快得多,即使扫描了数百个站点也能正常工作。也许你也应该试试。唯一的问题是,它没有您可以在jsdom中使用的所有选择器

希望它对你也有用


Daniel

使用jsdom 0.6.0帮助刮取一些数据时遇到了同样的问题。
window.close
只会帮助减缓内存泄漏,但它最终会慢慢上升,直到进程被终止

使用
节点--公开gc myscript.js

在修复内存泄漏之前,除了调用
窗口外,还可以手动调用垃圾收集器。关闭
似乎可以:

if (process.memoryUsage().heapUsed > 200000000) { // memory use is above 200MB
    global.gc();
}
在呼叫window.close后卡住了。每次触发时,内存使用都会立即下降到基线(对我来说大约50MB)。几乎觉察不到的停顿

Update:还应考虑多次调用“代码> Global .gc-())/COD>而不是仅一次(即<代码> Global .gc-();Global .gc-();Global .gc-();Global .gc-();Global .gc-(;)/ <代码>

多次调用window.gc()更有效(基于我不完善的测试),我怀疑是因为它可能导致chrome触发一个主要的gc事件,而不是一个次要的事件。-


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


CheapSteaks的答案证实了这一点,它手动强制垃圾收集。如果这样做有效的话,jsdom中就不会有内存泄漏,因为根据定义,内存泄漏会阻止垃圾收集器收集泄漏的内存。

使用gulp、内存使用、清理、变量删除、window.close()

对于7k文件,我的使用量通常在200mb到300mb之间。花了30分钟。
这可能对某些人有帮助,因为我在谷歌上搜索了一下,没有发现任何有用的东西。

解决方法是在分叉的child_进程中运行与jsdom相关的代码,并在完成后返回相关结果。然后杀掉孩子。

Daniel,谢谢你的回复。我会尝试一下,但我并不乐观。代码使用的是d3,似乎有一些选择器的东西。你找到解决方案了吗?@tknow-很抱歉回复太晚。目前为止,我还没有不幸地尝试过。请在0.5.1上再次尝试。同样的结果:(哇,cheerio快多了,使用的内存也少多了。cheerio中没有$(…).get(0)。我不得不用$(…)[0]来代替。谢谢!这个评论很有意义。也就是说,代码试图重新处理一个问题,内存不断增长,gc有足够的时间启动(网络服务器)。这可能表明这是两个不同的问题。我认为Node.js垃圾收集器使用的V8引擎确实“停止了世界垃圾收集”,因此不应该关心给他时间。(我知道这个答案很旧,但我的评论可能可以帮助一些用户解决问题)在我的例子中,我还必须在
global.gc()
之后添加一个500毫秒的睡眠时间,以便它真正释放内存:
等待新的承诺(resolve=>setTimeout(resolve,500));
尝试setimmidate(()=>global.gc())和window.close(),在减少内存消耗方面没有任何帮助。这并不能解决最初的问题,但您也可以使用更多堆内存启动节点进程,如:
node--max old space size=8192 index.js
if (process.memoryUsage().heapUsed > 200000000) { // memory use is above 200MB
    global.gc();
}
var gb = setInterval(function () {

    //only call if memory use is bove 200MB
    if (process.memoryUsage().heapUsed > 200000000) { 
        global.gc();
    }

}, 10000); // 10sec


gulp.task('tester', ['clean:raw2'], function() {

  return gulp.src('./raw/*.html')
    .pipe(logger())
    .pipe(map(function(contents, filename) {


        var doc = jsdom.jsdom(contents);
        var window = doc.parentWindow;
        var $ = jquery(window);

        console.log( $('title').text() );

        var html = window.document.documentElement.outerHTML;

        $( doc ).ready(function() {
            console.log( "document loaded" );
            window.close();
        });

        return html;
    }))
    .pipe(gulp.dest('./raw2'))
    .on('end', onEnd);
});