【发布时间】:2013-12-05 08:41:55
【问题描述】:
我是这种javascript的新手,所以我将做一个简单的解释:
我有一个内置于Nodejs 的网络爬虫,它收集(相当多的)数据,用Cheerio 处理它(基本上jQuery 用于Node)创建一个对象然后将其上传到mongoDB。
它工作得很好,除了在较大的网站上。 似乎正在发生的事情是:
- 我给爬虫一个网上商店的 URL 来爬取
- 节点转到该 URL 并检索 5,000 - 40,000 个产品 URL 以进行抓取
- 对于每个新 URL,Node 的
request模块获取页面源,然后将数据加载到Cheerio。 - 我使用 Cheerio 创建了一个代表产品的 JS 对象。
- 我将对象发送到 MongoDB 并保存到我的数据库中。
正如我所说,这种情况发生在数千个 URL 上,一旦我加载了 10,000 个 URL,我就会在 node.js 中遇到错误。最常见的是:
Node: Fatal JS Error: Process out of memory
好的,这是实际的问题:
我认为这是因为 Node 的垃圾清理工作不正常。例如,从所有 40,000 个 url 中抓取的 request 数据可能仍在内存中,或者至少创建的 40,000 个 javascript 对象可能仍在内存中。也许这也是因为 MongoDB 连接是在会话开始时建立的,并且从未关闭(我只是在所有产品完成后手动关闭脚本)。这是为了避免在我每次登录新产品时打开/关闭连接。
要真正确保它们被正确清理(一旦产品进入 MongoDB,我就不再使用它并且可以从内存中删除)我可以/应该只是简单地从内存中删除它,只需使用 delete product?
此外(我显然不了解 JS 如何处理对象)如果我删除一个对该对象的引用,它是从内存中完全擦除,还是必须全部删除?
例如:
var saveToDB = require ('./mongoDBFunction.js');
function getData(link){
request(link, function(data){
var $ = cheerio.load(data);
createProduct($)
})
}
function createProduct($)
var product = {
a: 'asadf',
b: 'asdfsd'
// there's about 50 lines of data in here in the real products but this is for brevity
}
product.name = $('.selector').dostuffwithitinjquery('etc');
saveToDB(product);
}
// In mongoDBFunction.js
exports.saveToDB(item){
db.products.save(item, function(err){
console.log("Item was successfully saved!");
delete item; // Will this completely delete the item from memory?
})
}
【问题讨论】:
标签: javascript node.js mongodb memory-management memory-leaks