Memory NodeJS 0.3.1应用程序内存泄漏
我有一个相当简单的NodeJS应用程序,它只不过是一个shell,它接受请求并使用可读性形式(基于)解析内容。问题是,我注意到应用程序内存泄漏——我运行了Memory NodeJS 0.3.1应用程序内存泄漏,memory,memory-leaks,node.js,Memory,Memory Leaks,Node.js,我有一个相当简单的NodeJS应用程序,它只不过是一个shell,它接受请求并使用可读性形式(基于)解析内容。问题是,我注意到应用程序内存泄漏——我运行了节点--trace gc,每次请求时内存都会慢慢积累,偶尔的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
节点--trace gc
,每次请求时内存都会慢慢积累,偶尔的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有时间运行之后,内存使用也不会减少
我或多或少相信我必须在某个地方分配一个全局变量,但我不知道如何修复它。此项目的代码位于此处:
有人对我应该做什么有什么建议(和理由吗?就像PartlyCloudy提到的那样,你应该将你的node.js实例更新到最新的版本0.4.0。希望这个bug已经被修复,否则你可以在github上提交一个over
我认为Ryan's不会用这个不稳定的旧版本修复任何bug。我将在这里回答我自己的问题,希望它能帮助其他人解决同样的问题 问题实际上与我在创建服务器时使用的event.emitter有关。当只使用一个连接时,没有内存泄漏(想想开发),但当应用程序开始受到攻击时,大量内存开始攀升,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
};
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
};
侦听器变量是从未被销毁的部分。我试图强制删除该变量,但随后响应从未发送到浏览器。答案是,我所要做的就是将侦听器变量移动到else if
语句中,当函数运行完毕时,它会自动被GC'ed
==
正确的代码
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
};
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
};
0.3.1不稳定,0.4.0已发布。你试过了吗?谢谢大家的建议-我在我的开发机器上更新到了0.4.0(服务器已经在0.4.0上了)-但是那没有帮助。见下面我的答案。