我找到了一些提到类似问题的人的答案总是如此,确保你在完成后调用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");
我得到的输出是
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 }
此时风扇变得疯狂,测试实际上停止了......或者至少开始非常缓慢
是否有任何其他提示而不是window.close来摆脱内存泄漏(或者它确实看起来像内存泄漏)
谢谢!
彼得
答案 0 :(得分:10)
使用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();
}
在调用window.close后被困住了。每次触发时,内存使用会立即回落到基线(对我来说大约50MB)。几乎感觉不到停止。
答案 1 :(得分:4)
您没有给程序任何空闲时间进行垃圾回收。我相信你会遇到同样的问题,任何大型对象图在一个没有中断的循环中被多次创建。
这可以通过CheapSteaks的回答来证实,它可以手动强制进行垃圾回收。如果可行的话,jsdom中不会有内存泄漏,因为根据定义,内存泄漏会阻止垃圾收集器收集泄漏的内存。
答案 2 :(得分:3)
我遇到了与jsdom相同的问题并切换到cheerio,这比jsdom快得多,即使扫描了数百个网站也能正常工作。也许你应该尝试一下。唯一的问题是,它具有你可以在jsdom中使用的所有选择器。
希望它也适合你。
丹尼尔
答案 3 :(得分:1)
gulp,内存使用,清理,变量删除,window.close()
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);
});
对于7k文件,我的使用率在200mb到300mb之间。花了30分钟。
这可能对某些人有帮助,因为我用谷歌搜索并没有找到任何有用的东西。
答案 4 :(得分:0)
解决这个问题的方法是在分叉的 child_process 中运行与 jsdom 相关的代码,并在完成后发回相关结果。然后杀死 child_process。