一个多月以来,我一直在努力解决一个非常烦人的内存泄漏问题,我不知道如何解决它。
我正在编写基于以下内容的通用网络爬虫:http,async,cheerio和nano。从一开始我就一直在努力解决内存泄漏问题。 我知道可以使用谷歌浏览器进行堆转换并对其进行分析,但我无法理解输出。它通常是一堆无意义的字符串和对象导致一些匿名函数告诉我什么都没有(可能是我缺乏经验)。
最终我得出的结论是,我当时使用的库(jQuery)存在问题,我将其替换为Cheerio。我有一个印象,Cheerio解决了这个问题,但现在我确信它只会减少它的戏剧性。
您可以在https://github.com/lukaszkujawa/node-web-crawler找到我的代码。我知道可能需要分析很多代码,但也许我正在做一些愚蠢的事情,这可能是显而易见的。我怀疑主代理类从多个“线程”(带async.queue
)执行HTTP请求https://github.com/lukaszkujawa/node-web-crawler/blob/master/webcrawler/agent.js。
如果您想运行代码,则需要使用CouchDB,并在npm install
之后执行:
$ node crawler.js -c conf.example.json
我知道Node不会对垃圾收集感到疯狂,但经过10分钟的重度爬行后,使用的内存可以轻松超过1GB。
(使用v0.10.21和v0.10.22测试)
答案 0 :(得分:4)
对于它的价值,即使您实际使用的内存不是很大,Node的内存使用量也会增长和增长。这是为了代表V8引擎进行优化。要查看您的实际内存使用情况(以确定是否存在实际的内存泄漏),请考虑将此代码(或类似代码)放入您的应用程序中:
setInterval(function () {
if (typeof gc === 'function') {
gc();
}
applog.debug('Memory Usage', process.memoryUsage());
}, 60000);
运行node --expose-gc yourApp.js
。每分钟都会有一条日志行,表示在强制垃圾收集后立即使用实际内存。我发现随着时间的推移观察这个输出是确定是否存在泄漏的好方法。
如果您发现泄漏,我发现调试它的最佳方法是一次消除大部分代码。如果泄漏消失,请将其放回并消除其中的一小部分。使用此方法将其缩小到发生问题的位置。闭包是一个常见的来源,但也检查其他任何参考可能无法清理。许多网络应用程序将为未立即销毁的套接字附加处理程序。