socket.io: Socket.io memory doesn't drop of after clients disconnect

I use the most simple example

var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');

app.listen(1994);

function handler(req, res) {
    res.end('socket.io start')
}

io.on('connection', function(socket) {});

I use socket.io-client, create a 4k connections Then I closed the client, find memory doesn’t drop.

socket.on('disconnect', funtion() {
    delete io.sockets[socket.id];
    delete io.sockets.sockets[socket.id];
});

heapUsed decreased slightly rss and heapTotal without any change

SOS

The memory is cleaned up by the garbage collectors periodically. But I waited for half an hour, still no change. Can I only use global.gc() to forcibly reclaim memory it?

@nuclearace

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 4
  • Comments: 26 (6 by maintainers)

Most upvoted comments

lol was this fixed? i’m scared to use sockets.io because i keep hearing about this issue

That issue was closed automatically. Please check if your issue is fixed with the latest release, and reopen if needed (with a fiddle reproducing the issue if possible).

This is not good. Issue still seems to exist. Definetly a very critical bug right here.

ping

Hello?

in last version (4.1.3), disconnected sockets (from like network loss or just closing the browser) will remain in the memory forever…

You can easly check this with IO.sockets.sockets

In previous version we were able to loop over IO.sockets.connected and if the row was === to undefined, we could drop it. But now we only have IO.sockets.sockets, and all row are undefined, connected or not so that’s not a solution anymore.

And relying on “disconnect” event is not a solution as it does not trigger 100% of the time a connection gets dropped

Yup… the issue is still there and I found it in the worst scenario possible. A production server exploded.

It should be AT LEAST stated in the docs that the sockets objects are never deleted from memory and where they are stored, so we can come up with a way to get rid of them.

For those who are about to lose their heads with this:

What solved the leak for me was this: force the clients to connect via the “websocket” protocol.

import { io } from 'socket.io-client'

// ...

io(url, {
   transports: ['websocket']
})

I believe this is because socket.io defaults to HTTP polling in some scenarios, even if the client supports websocket. I’m not sure, since I don’t know the internals of the package and also if this is the expected behavior or a bug. What I DO KNOW is that I’m running a chat app for over a year now and everything is running smoothly without leaks since I took this route…

Ok, update on this. I have been able to fix the issue. However I don’t have the exact fix available anymore. I might provide it in the future but I’ll have to look up the code base. What I remember is there’s an array/object which does never get cleared. I think it’s the internal onclose that wouldn’t remove a connection. It’s definitely fixable I had it fixed back then.