Sphinx
Sphinx

Reputation: 109

Removing items and freeing memory in JavaScript

How to properly delete items from multidimensional associative arrays (OK, OK - objects)? Is it enough just to call delete for them? Maybe I should explicitly call global.gc() with some time period?

Here is part of my Node.js server code. I've noticed that memory consumption grows day after day, it rises on high load peaks, then lowers, but never comes back. Please, help me!

I am using Node.js 4.1.2 and Socket.IO 1.3.7

var sockets = []; // global sockets storage
var channels = []; // global users storage (grouped by channels)

/* ... */

function SOCKET_ON_channel_subscribe(socket, data) {
    var user_sockets = [];
    user_sockets.push(socket.id);
    var user = {
        sockets: user_sockets,
        info: user_info
    };

    // add user
    if (channels[channel] == undefined) channels[channel] = [];
    channels[channel][user_id] = user;
    sockets[socket.id] = {channel: channel, user_id: user_id};
}

function SOCKET_ON_disconnect(socket) {
    if (sockets[socket.id] != undefined) {
        var channel = sockets[socket.id].channel;
        var user_id = sockets[socket.id].user_id;

        // detach socket and delete it
        var index = channels[channel][user_id].sockets.indexOf(socket.id);
        channels[channel][user_id].sockets.splice(index, 1);
        delete sockets[socket.id];

        // no more attached sockets? delete user
        if (channels[channel][user_id].sockets.length == 0) {
            delete channels[channel][user_id];
            if (arrSize(channels[channel]) == 0) delete channels[channel];
        }
    }
}

/* ... */

function arrSize(arr) {
    var size = 0, key;
    for (key in arr) {
        if (arr.hasOwnProperty(key)) size++;
    }
    return size;
}

Upvotes: 1

Views: 1142

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074038

Is it enough just to call delete for them?

delete doesn't remove objects from memory per se. It just removes the property from the object. If that property was the only thing referencing the object it referred to, them yes, that's sufficient, because nothing else will be referring to the object, and eventually V8 will reclaim the memory (once there's some memory pressure). If anything else is referring to it, then deleting the property just deletes the property.

Maybe I should explicitly call global.gc() with some time period?

This shouldn't normally be necessary.

...it rises on high load peaks, then lowers, but never comes back.

If by "never comes back" you mean it never goes all the way back down, then you do probably have a memory leak somewhere. It's hard to suggest where that might be with such incomplete code (what's channel, for instance?), but it looks like you're using arrays both for their array-ness (indexOf, splice) and for their object features (non-index property names). I'd probably separate those two uses out, conflating them like that is, at least, confusing.

Upvotes: 4

Related Questions