如何在node.js中跟踪堆内的对象来查找内存泄漏?

时间:2014-07-31 15:48:19

标签: node.js memory-leaks

我有内存泄漏,我知道它在哪里(我想是这样),但我不知道它为什么会发生。 在端点(使用restify.js服务器)进行负载测试时发生内存泄漏:

server.get('/test',function(req,res,next){
    fetchSomeDataFromDB().done(function(err,rows){
        res.json({ items: rows })
        next()
    })
})

我很确定res对象没有处理(通过垃圾收集器)。应用程序使用的每个请求内存都在增长。我做了一些额外的测试:

var data = {}
for(var i = 0; i < 500; ++i) {
    data['key'+i] = 'abcdefghijklmnoprstuwxyz1234567890_'+i
}
server.get('/test',function(req,res,next){
    fetchSomeDataFromDB().done(function(err,rows){
        res._someVar = _.extend({},data)
        res.json({ items: rows })
        next()
    })
})

因此,在每个请求中,我将大对象分配给res对象作为其属性。我观察到,通过这个附加属性,内存增长得更快。内存在60秒内每1000次请求增长100Mb。下一次相同的测试内存再次增加100mb,依此类推。现在当我知道res对象没有被释放时#34;我如何跟踪仍然保持对res的引用?假设我将执行堆快照 - 我如何找到引用res的内容?


10个请求之间的堆比较截图:

enter image description here

实际上似乎Instance.DAO正在泄漏?这个类属于我用来查询DB的ORM ...你怎么看?

按#delta排序的另一个相同的比较屏幕:

enter image description here

1 个答案:

答案 0 :(得分:0)

由于您没有在此代码中的任何位置泄漏res,因此GC似乎还没有收集到该对象。尝试使用--expose-gc节点参数运行脚本,然后设置定期调用gc();的时间间隔。这将强制GC运行而不是懒惰。

如果之后您发现 确实泄漏了内存,您可以使用heapdump模块之类的工具来使用Chrome开发人员堆检查器来查看占用空间的对象。