带有 Socket.IO 1.0 的 NodeJS - 堆外的内存泄漏

Posted

技术标签:

【中文标题】带有 Socket.IO 1.0 的 NodeJS - 堆外的内存泄漏【英文标题】:NodeJS with Socket.IO 1.0 - memory leak outside of heap 【发布时间】:2014-10-16 14:44:59 【问题描述】:

我们一直在尝试使用 Socket.IO 部署一个小型 NodeJS 应用程序,并且遇到了一个问题,即虽然应用程序的堆大小仍然可以接受,但使用后的总内存 (rss) 攀升至超过 2gb大约 2 小时,并继续上升。

为了确保问题不在我们的代码中,我们部署了一个简单的应用程序,除了初始化 Socket IO 之外没有任何自定义逻辑。我们针对相同的生产流量运行它,并遇到了同样的问题。

每 10 秒我们输出以下数据:rss 内存使用情况、堆总数、堆计数和连接计数。以下是输出示例:

523898880 199490816 123040352 2001
537059328 209774080 163828336 2011
538578944 206714368 150879848 2031
535252992 199514880 156743280 2041
542162944 200522752 145077944 2039
539652096 195387136 129486792 2055
551006208 206726400 170918304 2070
553254912 205706496 156447496 2071
550584320 198482944 154005496 2076
564363264 209810176 140442920 2095
561176576 201578752 123214232 2118
562487296 200546816 110638376 2112
572096512 206714368 162713240 2133
569552896 200546816 147439016 2121
577777664 205682432 136653448 2115
582496256 207770368 121204056 2133
582909952 205706496 115449888 2153
597364736 215989760 164582600 2158
590491648 204686592 148962008 2158
598315008 209810176 137608840 2164
598249472 205718528 123472944 2188
607158272 211898112 160187496 2168
609869824 210866176 154986472 2161
618110976 214969856 142425488 2180
615014400 207782400 119745816 2188
623575040 214981888 163602944 2180
624717824 210842112 147051160 2189
627556352 210866176 142542800 2191
636477440 216013824 129968776 2203
643809280 221149440 162858408 2219
644407296 217057792 154994536 2224
642068480 211922176 141626008 2240
649084928 214969856 123126792 2267
662454272 224233216 166539024 2272
659439616 217045760 162742688 2258
662867968 217057792 137425392 2266
667013120 218065664 119616592 2261
673230848 220129536 172101080 2272
677904384 220129536 149771776 2267
676691968 217045760 129936448 2267
674639872 211898112 125941816 2277
689025024 223225344 163745856 2274
689991680 219109632 151478936 2282
698601472 225301248 137102712 2298
706170880 229428992 171321288 2306
705675264 224257280 160088496 2303
701198336 217033728 149326384 2313
701833216 216013824 129806072 2314
718053376 227365120 184078288 2335
718950400 223225344 157977312 2333
717037568 218065664 146137456 2354
714428416 210890240 136566344 2381

如您所见,在相当短的时间内,总内存使用量增加了 200mb,尽管连接数仅增加了 400 左右。堆使用量大致保持不变,只是稍微高了一点连接数越高。

我们在 64 位的 Debian Wheezy 上运行。 NodeJS 版本为 0.10.29,Socket IO 版本为 1.0.6。我们使用的代码是:

var http = require('http'),
    io = require('socket.io');

var app = http.createServer();
var server = io(app);
app.listen(80);
var connections = 0;

server.on('connection', function(socket) 
    connections++;

    socket.on('disconnect', function() 
        connections--;
    );
);

setInterval(function() 
    var mem = process.memoryUsage();
    console.log(mem.rss + ' ' + mem.heapTotal + ' ' + mem.heapUsed + ' ' + connections);
, 10000);

我们有什么方法可以找出为什么 Node 总共使用了这么多内存,或者有什么方法可以查看堆外部发生的情况以尝试找出内存泄漏?我们已经尝试了所有检查堆使用情况的常用技巧,但一无所获,但没想到会出现,因为问题似乎与堆上的内存无关。

【问题讨论】:

不是console.log造成的吗? 【参考方案1】:

如果您认为 node.js 模块存在内存泄漏,从进程中获取系统内存快照将提供不准确的结果。

最好使用valgrind、gdb、prstat 和dtrace 等工具。 Joyent 甚至提供了nice module 来帮助您可视化相关过程。

【讨论】:

以上是关于带有 Socket.IO 1.0 的 NodeJS - 堆外的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

带有 socket.io 的 WebRTC/nodejs 中的屏幕共享问题

在多核服务器中使用带有集群的 socket.io 的好方法?

带有 socket.io 的节点服务器不会建立连接

在nodeJs中将pm2与socket io集成[关闭]

NodeJs Socket.io Rooms

我们可以在 Node JS 应用程序中使用带有 ejs(嵌入式 javascript)的 socket.io 而不是 html 页面吗?