soso
soso

Reputation: 181

JavaScript Closure Memory Leak

I have a Javascript garbage collection/memory leak question. I'm using Chrome 28.0.1500.71 on OS X 10.8.4.

The following code never deallocates the space that was held by me and I'm clueless as to why.

var MyClass = function() {
    this.x = 1;

    var self = this;
    this.do_thing = function() {
        self.x++;
    };
};
MyClass.prototype.destroy = function() {
    delete this.do_thing;
};

var me = new MyClass();
me.do_thing();
me.destroy();
me = null;

// the MyClass object formerly known as 'me' is still allocated here
// (as evidenced by Chrome's heap profiler)

Chrome seems to keep the object created by the expression new MyClass() (the object that me pointed to before being set to null) in memory because it is referenced by self in the call to me.do_thing(). However, I would have thought the call to destroy(), which unsets me.do_thing would throw away the variables in the scope of the constructor (self in the new MyClass() call).

I have also tried using Underscore.JS's _.bind function but run into the same unresolved problem described here: Instances referenced by 'bound_this' only are not garbage collected.

Upvotes: 5

Views: 705

Answers (4)

alph
alph

Reputation: 676

Looks like a bug. Btw me.destroy() is not necessary. It should be deleted without it.

Upvotes: 0

simonleung
simonleung

Reputation: 44

MyClass is a global variable. It is also a property of window object in browser environment. It is not a garbage so of couse it will not be collected.

Upvotes: 0

basilikum
basilikum

Reputation: 10528

I don't know why it is not garbage collected, but adding the destroy method to the instance instead of the prototype and setting self to null, will apparently work:

var MyClass = function() {
    this.x = 1;

    var self = this;
    this.do_thing = function() {
        self.x++;
    };

    this.destroy = function() {
        delete this.do_thing;
        self = null;
    };
};

var me = new MyClass();
me.do_thing();
me.destroy();
me = null;

Upvotes: 1

simonleung
simonleung

Reputation: 21

me is still a property of window object even you set it to null. Thus "me" is still in the memory.

I think this may help:

window.me = new MyClass();
me.do_thing();
delete window.me;

Upvotes: 0

Related Questions