Node.js 在节点js中从未释放已用内存。很奇怪

Node.js 在节点js中从未释放已用内存。很奇怪,node.js,memory-leaks,Node.js,Memory Leaks,我刚刚完成了我的第一个node.js应用程序的开发,现在我正在我的VPS上测试它。通过观察进程“节点”的资源使用情况,我注意到当请求一个页面(尤其是一些页面)时,内存使用量会增加。特别是,如果请求的页面是静态页面,则增加的幅度最小。如果请求的页面为/admin,则增加的容量可能为1mb!当然,当请求/admin时,我的服务器所做的事情比为静态页面提供服务要多。他连接到mongodb,执行4次“查找”,使用将结果绑定到html模板。现在,有什么问题吗?此内存已使用,将永远不会释放!!!所以我认为我

我刚刚完成了我的第一个node.js应用程序的开发,现在我正在我的VPS上测试它。通过观察进程“节点”的资源使用情况,我注意到当请求一个页面(尤其是一些页面)时,内存使用量会增加。特别是,如果请求的页面是静态页面,则增加的幅度最小。如果请求的页面为/admin,则增加的容量可能为1mb!当然,当请求/admin时,我的服务器所做的事情比为静态页面提供服务要多。他连接到mongodb,执行4次“查找”,使用将结果绑定到html模板。现在,有什么问题吗?此内存已使用,将永远不会释放!!!所以我认为我的代码中有一个逻辑错误,但后来我做了另一个更有趣的测试

考虑这个非常简单的nodejs服务器:

 var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(3000, 'my_public_ip');
如果我尝试使用浏览器发出多个请求(只需按住f5键一分钟),内存使用量增长缓慢,进程使用的内存将永远不会释放,即使在长时间关闭浏览器后也是如此。现在,在我的/admin代码中可能存在一些错误(每个请求使用了1mb的内存,但从未释放过,这非常高!),但我认为上面的简单脚本使用的内存永远不会释放,这非常奇怪!你觉得这个怎么样?有办法避免吗

此外,(在我的真实服务器中),我以以下方式使用:

    var memwatch = require('memwatch');
    memwatch.on('leak', function(info) {
       console.log(info); 
       process.exit(1);
    });
如果我使用浏览器执行多个请求,则在执行该操作大约10秒后,进程将退出,这是错误:

{ start: Wed Nov 26 2014 08:21:07 GMT-0500 (EST),
  end: Wed Nov 26 2014 08:22:04 GMT-0500 (EST),
  growth: 4775624,
  reason: 'heap growth over 5 consecutive GCs (57s) - 287.65 mb/hr' }

这是什么意思??它似乎与垃圾收集器有关!我知道最好在这里粘贴我的/管理代码,但代码段很长,并且与全局变量相关,因此如果没有200行的副本,就无法理解:D。如果您需要更多信息,我将提供给您

节点没有释放内存并不奇怪,大多数程序都没有。它们是贪婪的:如果内存不足,它们会从系统中获得更多内存。如果他们有多余的,他们会留到以后

短示例服务器没有泄漏内存。我使用节点v0.10.29运行了14分钟的测试;内存使用只在最初缓慢增长,然后停止。每个http调用的增长率不到一位,因此不会在调用本身中泄漏内存。nodejs运行时导致的内存碎片可能会导致堆增长,直到有足够的空闲内存来弥补碎片

14分钟后,nodejs进程仍然只使用21MB堆中的2MB,就像它启动时一样。(14因为15分钟的运行暂停了1:09)

以下是超过246万个http调用的增长(仅显示heapTotal更改和final。最终内存占用在4分钟后达到,在接下来的11分钟内不会更改):

2014-12-03T04:52:48.358Z{rss:12222464,heapTotal:7130752,heapUsed:1751228}
2014-12-03T04:52:55.182Z{rss:17326080,heapTotal:9227904,heapUsed:2186528}
2014-12-03T04:53:59.488Z{rss:21172224,heapTotal:13422208,heapUsed:2092796}
2014-12-03T04:56:58.897Z{rss:29556736,heapTotal:21810816,heapUsed:2100000}
(…在05:02:27左右暂停了1:09)
2014-12-03T05:07:45.598Z{rss:29446144,heapTotal:21810816,heapUsed:2138608}

我的(稍微修改的)测试:


您是否尝试手动强制垃圾收集?选中:“使用-nouse_idle_notification和-expose_gc标志启动节点,然后当您想要运行gc时,只需调用global.gc()。”您可以在gist/pastebin中发布代码。但是你提到全局变量这一简单事实应该会触发一个警报:)我们确实需要更多信息。另外,尝试
memwatch
hot代码,不要在启动后立即使用。我(Andras)使用强制gc尝试了上述代码,这是非常渐进的,但有些事情正在发生。在超过200秒和580000次呼叫中,heapUsed增加了40KB(很小),但heapTotal增加了12MB,先是+4,然后是+8。我跑了5分钟,现在我收回它,我不再认为它是一个漏洞。从长期来看,内存使用似乎是稳定的。
var ncalls = 0;
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
  if (ncalls++ % 100000 === 0) {
    global.gc();
    console.log(new Date().toISOString(), process.memoryUsage());
  }
}).listen(3000, '127.0.0.1');
console.log("Listening on 3000...");