这是我得到的错误:
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
这是代码。注意我添加了process.nextTick
以按照另一篇文章中的建议进行递归调用,但我仍然收到内存错误。
function req(url){
return new Promise(function (resolve, reject) {
request({
url: url
}, function (err, res, body) {
if (err) {
console.trace(err);
return reject(err);
} else if (res.statusCode !== 200) {
err = new Error("Unexpected status code: " + res.statusCode);
err.res = res;
console.trace(err);
return reject(err);
}
resolve(body);
});
});
}
function getNextUrl(url){
var page = provider.results.page(url);
nextPages.push(url);
req(url)
.then(function (body) {
var $ = cheerio.load(body)
, $profileUrls = provider.results.profileUrls($)
, nextUrl = provider.results.next($, url);
async.eachLimit($profileUrls, argv.concurrent, function(el, cb){
var $el = $(el)
, profileUrl = provider.results.profileUrl($, $el);
getProfileUrl(profileUrl, url)
.then(function(body){
cb(null);
}, function(err){
console.trace(err);
});
}, function(err){
if ( err ) {
return console.trace(err);
}
console.log('Done with profile urls.'.info);
//here is the recursive call
process.nextTick(function(){
getNextUrl(nextUrl);
});
});
}, function(err){
console.trace(err);
});
}
getNextUrl(startUrl);
此代码运行正常,大约10k网址,但如果我将其提高到20k,我会收到此错误。我需要它能够超过20k,也许是200k的初学者。我希望这件事最终只能处理任何数字而不会崩溃。
当async.eachLimit
完成时,它会在新网址上调用自己。我怀疑这是问题的根源。我在一个对象数组中收集了一些数据,但是当我将这个JSON写入磁盘时,它只有大约5mb,而我的系统有1gb的ram。
答案 0 :(得分:2)
为了将来参考,我对related issue的回复:
这应该与cheerio#263相关:URL是原始文档的片段,维护它们意味着将整个文档保留在内存中。在20k页之后,你将耗尽内存。修复方法是强制V8创建副本,例如。通过使用(“”+ url).substr(1)。