views:

55

answers:

2

I have two piece of code sample 1

(function(){

var x = 1;

 this.getx = function() { return x; };

})();

sample 2

(function(){

var x = 1;

 this.getx = function() { };

})();

both code samples create a closure, x in sample one is referenced, while x in sample two is not referenced, I know x in sample one will not be garbage collected, my question will x in sample two be garbage collected? Thanks

+1  A: 

The ECMAScript standard is intentionally silent on how the garbage collector should work so implementations are likely to differ. However, in general, if an object is not referencible from a live object it will be collected.

In sample 2 it means that the closure will likely be collected but it is also likely a closure will not even be created since the function does not reference it. Closures are expensive and modern JavaScript engines try to avoid creating them unless they are forced to.

chuckj
is this specification of of ECMAScript that construct like sample 2 will not create a closure? I just want to understand how the gc works, so that I know how to write my code better.
Fred Yang
No. The standard only specifies observable effects, but since it is clear from the code that one is not necessary it is likely one will not be created.
chuckj
is there any profiler to see how engine allocate and collection memory in js engine?
Fred Yang
Chrome appears to have one in their developer tools called "Heap Snapshot". I haven't used it so I cannot say whether it will help you.
chuckj
A: 

Garbage collection in Javascript is a nebulous thing. Generally speaking, you can assume (though we know what assuming does) that once there are no references to a variable (eg, once it goes out of scope), it will be garbage collected. However, your closures will not work as you intend because they are not assigned to anything; thus you will have no function object to call getx() on. If you were to assign it, though, x would never be out of scope unless you used the delete keyword on any variables holding the function reference.

Simple rule: use the delete operator whenever you're concerned about collection - this will remove the reference, and it's more likely that the memory will be freed.

Edit: comments by @chuckj aside, whether you use delete or assign the variable to undefined still lends to the point that you want to get the reference count to 0 if there's to be any hope of freeing the memory.

mway
Using delete in this fashion is really bad advice. In modern engines this will likely cause a type transition which could be very expensive. It is better just set the variable to undefined.
chuckj
Any reference to support that?
mway
Any talk by Lars Bak on the architecture of V8 should be sufficient. In general, don't use delete on an object unless it is really being used as a hashtable. Doing so will likely cause the object be converted to an inefficient representation.
chuckj