Reputation: 109
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
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