Dex Dex - 7 months ago 12
Javascript Question

Will my 'new Object' be garbage collected on socket disconnect

I've got a code setup and I would like to know if it gets garbage-collected so my system won't start swapping and freeze/crash.

The setup should be able to run an undetermined amount of time assuming you stay within the normal parameters of your system (e.g. so don't connect 1.000.000 users to one single thread process all at the same time)

I've made a simplified version.

// connection.js

var io, Handler;
io = require('socket.io');
Handler = require('./handler');

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


// handler.js

var Handler,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

function Handler(arg) {
this.socket = arg.socket;
this.test = bind(this.test, this);
console.log('Handler', 'New connection', this.socket.id);
this.listeners();
}

Handler.prototype.listeners = function() {
return this.socket.on('test', this.test);
};

Handler.prototype.test = function() {
return console.log('SocketIO', 'test', this.socket.id);
};


module.exports = Handler;


So is 'new Handler' garbage-collected after a 'socket disconnect event' has occurred?

If not how should I change the code?

At first I thought this might solve the problem

var io, connections, Handler;
io = require('socket.io');
Handler = require('./handler');
connections = {}

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

connections[socket.id] = new Handler({socket: socket});

socket.on('disconnect', function (){
connections[socket.id] = null
})
});


But this only creates a reference to the 'new Handler' and removes that same reference on disconnect. That doesn't necessarily mean the 'new Handler' will be removed as well. It could still be listening for and/or doing stuff.

Answer

Your Handler object should get garbage collected as long as no other code of yours is keeping a reference to it.

When the actual socket itself is closed, the system knows that the event handlers are no longer live and thus they don't prevent garbage collection. The browser does the same sort of thing when you remove a DOM object that has event handlers on it so that these event handlers don't prevent garbage collection.

So, when the socket is closed and socket.io releases any references it has to the Javascript socket object, there should be no code that has any references to the Handler object any more and it will be eligible for garbage collection.

If you make your own reference to the Handler object such as:

var connections = {};
io.on('connection', function (socket) {
    connections[socket.id] = new Handler({socket: socket});
});

Then, you will have to clear that reference upon disconnect as in the code below. Otherwise, this reference will stay alive and will keep the Handler object from being garbage collected.

var connections = {};
io.on('connection', function (socket) {
    connections[socket.id] = new Handler({socket: socket});

    socket.on('disconnect', function() {
        delete connections[socket.id];
    })
});

Note: I'd recommend you actually use delete to remove the property rather than just setting it to null. That way you won't get unused properties building up on the connections object.

Comments