我有内存泄漏,我知道它在哪里(我想是这样的),但我不知道为什么会发生。负载测试以下endpoint(使用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()
})
})
因此,在每个请求中,我都将big object分配给res
对象作为其属性。我观察到,有了这个附加属性,内存增长得快得多。在60秒内每完成1000个请求,内存会增加100MB。在下一次相同的测试之后,内存再次增长100MB,以此类推。现在,当我知道res对象没有被“释放”时,我如何跟踪什么仍然保持对res的引用?假设我将执行堆快照--如何找到引用RE的内容?
10个请求之间的堆对比截图:
实际上,instance.dao
似乎正在泄漏??这个类属于ORM,我正在使用它来查询DB...你觉得呢?
多一个按#delta排序的相同coparison屏幕:
GC似乎还没有收集对象,因为您没有在代码中的任何地方泄漏res
。尝试使用--expose-gc
节点参数运行脚本,然后设置定期调用gc();
的间隔。这将迫使GC运行而不是懒惰。
如果之后您发现确实有内存泄漏,您可以使用heapdump模块之类的工具来使用Chrome developer堆检查器来查看哪些对象占用了空间。