NodeJS 0.3.1应用程序泄漏内存

我有一个相当简单的NodeJS应用程序,它只是一个接受请求并使用Readability(基于https://github.com/arrix/node-readability )的formsparsing内容的shell。 问题是,我注意到应用程序泄漏内存 – 我已经运行node --trace-gc跟踪node --trace-gc和内存缓慢build立与每个请求偶尔gc传递无所事事。

 $ node --trace-gc server.js Scavenge 2.3 -> 2.3 MB, 1 ms. Mark-sweep 3.5 -> 2.9 MB, 2 ms. Scavenge 4.4 -> 3.8 MB, 0 ms. 16 Feb 10:57:51 - Server started on PORT 8000 Scavenge 5.9 -> 5.0 MB, 2 ms. Mark-sweep 5.0 -> 4.2 MB, 3 ms. Mark-compact 4.2 -> 4.1 MB, 7 ms. Scavenge 5.2 -> 4.7 MB, 1 ms. Scavenge 5.5 -> 5.1 MB, 1 ms. Scavenge 5.9 -> 5.5 MB, 1 ms. Scavenge 7.1 -> 6.3 MB, 2 ms. Scavenge 7.8 -> 7.0 MB, 2 ms. Mark-sweep 8.5 -> 7.6 MB, 10 ms. Scavenge 11.7 -> 9.7 MB, 4 ms. Scavenge 12.7 -> 11.2 MB, 5 ms. Mark-sweep 14.2 -> 12.4 MB, 21 ms. Scavenge 20.5 -> 16.5 MB, 10 ms. Scavenge 22.5 -> 19.5 MB, 11 ms. Mark-sweep 25.5 -> 22.4 MB, 38 ms. Scavenge 36.6 -> 29.6 MB, 25 ms. Scavenge 41.6 -> 35.6 MB, 24 ms. Mark-sweep 46.8 -> 41.1 MB, 75 ms. Scavenge 46.8 -> 44.0 MB, 33 ms. Mark-sweep 57.2 -> 50.6 MB, 92 ms. Scavenge 62.3 -> 56.5 MB, 26 ms. Scavenge 68.5 -> 62.6 MB, 24 ms. Scavenge 74.6 -> 68.6 MB, 26 ms. Mark-sweep 80.6 -> 74.5 MB, 130 ms. Scavenge 80.5 -> 77.6 MB, 25 ms. Mark-sweep 77.6 -> 77.4 MB, 112 ms. Mark-compact 77.4 -> 77.4 MB, 260 ms. 

即使请求停止后,GC有时间来反复运行,内存使用量也不会减less。

我或多或less相信,我必须分配一个全局variables的地方,但我不知道如何解决它。 这个项目的代码在这里:

https://github.com/erskingardner/Readable

有人有什么build议(和推理)我应该做什么?

我会在这里回答我自己的问题,希望能帮助其他有同样问题的人。

问题实际上是用event.emitter来创build服务器。 当只有一个连接被使用时,没有内存泄漏(认为是开发),但是当应用程序开始受到打击时,很多内存开始爬上爬,GC没有做任何事情。 我把一个事件监听器放在了一个高的链中,因此我创build了一个从未被销毁的事件监听器。

==

破解代码

 Readable.prototype.createHTTPServer = function() { var self = this; var server = http.createServer(function(request, response) { request.addListener('end', function() { var location = url.parse(request.url, true) ,params = (location.query || request.headers) ,body = ""; if (location.pathname == '/' && request.method == "GET"){ if (params["url"] == null){ response.writeHead(200, { 'Content-Type': 'text/html' }); response.end("Good to go, you might want to try adding a url param though."); } else if (params["url"] != null){ self.fetchAndParse(params["url"], params); } var listener = emitter.on("readability", function(result) { response.writeHead(200, { 'Content-Type': 'text/html' }); if (result == "error"){ response.end("error"); } else { response.end(result.content); } }); } }); }); return server }; 

监听variables是从未被销毁的部分。 我试图强制删除该variables,但是这个响应从来没有把它传递给浏览器。 答案是,我所要做的就是将这个listener var移动到else if语句中,并且在函数运行完成后自动被GC调用。

==

正确的代码

 Readable.prototype.createHTTPServer = function() { var self = this; var server = http.createServer(function(request, response) { request.addListener('end', function() { var location = url.parse(request.url, true) ,params = (location.query || request.headers) ,body = ""; if (location.pathname == '/' && request.method == "GET"){ if (params["url"] == null){ response.writeHead(200, { 'Content-Type': 'text/html' }); response.end("Good to go, you might want to try adding a url param though."); } else if (params["url"] != null){ self.fetchAndParse(params["url"], params); var listener = emitter.on("readability", function(result) { response.writeHead(200, { 'Content-Type': 'text/html' }); if (result == "error"){ response.end("error"); } else { response.end(result.content); } }); } } }); }); return server }; 

像PartlyCloudy提到,你应该真的把你的node.js实例更新到最新的最高版本v0.4.0。 希望这个bug已经修复,否则你可以在github上提交一个问题 。

我不认为Ryan将会修复那些旧的不稳定版本的错误。