nodejs , socket.io simple code memory leak

2019-04-06 23:35发布

问题:

i wrote code bellow using nodejs And socket.io for a simple socket application (just connect and disconnect ), for about 50 user memory usage not change to much , but for up to 300 user and after one hour , memory usage just grow up ( near 300MB for server.js proccess and grows by time pass ) , it's look like that nodejs don't release memory.

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 9090;
var sockets = {};

server.listen(port, function () {
    console.log('Server listening at port ', port);
    //timer and logs are not problem , i tested it before.
    setInterval(function(){
      console.log(Object.keys(sockets).length+' Online Devices At '+Date());
    }, 1000 * 60 * 1); 
});

io.on('connection',function(socket){
    sockets[socket.id]={id:socket.id};
    console.log('connected '+socket.id + ' count ' + Object.keys(sockets).length);
    socket.on('disconnect', function (data) {
        delete sockets[socket.id];
        console.log('disconnected '+socket.id+ ' count ' +Object.keys(sockets).length);
    });
});

am i doing some thing wrong ?!

Edit

14 hours after starting file with forever

300 open sockets And About 500MB of memory usage that is related to my nodejs proccess.

Edit

After 16 Hours , 300 Connected Sockets After process stopped.

ٍEdit

loot at my new code please.

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 90;
var counter = 0;
var clients = {}
server.listen(port, function () {
        console.log('Server listening at port ', port);
});
io.on("connection",function(socket){
        clients[socket.id] = socket;
        counter++;

        socket.on('disconnect', function (data) {
                counter--;
                delete clients[socket.id];
        });
});

i am trying this with 1000 connected user ( another server is simulate user requests and open sockets )

memory usage before start :100MB , after 5 minutes and 1000 stable open connections : 400MB

回答1:

V8 is lazy when it comes to freeing up unused memory, so it may look like a memory leak when it is actually just V8 not running its garbage collector. To see if this is the case, run your process with the --expose-gc flag set e.g.

node --expose-gc yourscript.js

And force manual garbage collection on an interval (I used 30 second interval).

setInterval(function(){
  global.gc();
  console.log('GC done')
}, 1000*30);


回答2:

The code looks fine. Your proposed memory leak is almost certainly not in the part of the code you have shared.

This isn't pertinent to your main question, but if you just wish to list the number of connected sockets, you should use an integer counter instead of calling Object.keys() on the sockets object, like this:

var express = require('express');
var app     = express();
var server  = require('http').createServer(app);
var io      = require('socket.io')(server);

var port = 9090;
var connectedSockets = 0;
var sockets = {};

server.listen(port, function () {
    console.log('Server listening at port ', port);
    //timer and logs are not problem , i tested it before.
    setInterval(function(){
      console.log(connectedSockets + ' Online Devices At ' + Date());
    }, 1000 * 60 * 1); 
});

io.on('connection',function(socket){
    if (!sockets[socket.id]) connectedSockets++;
    sockets[socket.id]={ id: socket.id };
    console.log('connected ' + socket.id + ' count ' + connectedSockets);
    socket.on('disconnect', function (data) {
        delete sockets[socket.id];
        connectedSockets--;
        console.log('disconnected ' + socket.id + ' count ' + connectedSockets );
    });
});