I have a question regarding garbage-collection in google chrome (Version 20.0.1132.47, Ubuntu 11.04 64bit).
While comparing heap-dumps and checking for memory-leaks, I discovered some instances, that are never cleaned up. Normally this behaviour can be tracked down to a programmer-error, but in this case I'm rather clueless..
Take a look at the following screenshot
The instance 'child @610739' is referenced only by 'bound_this' instances that belong to functions of the child-instance itself. So to my understanding, the child-instance should be garbage-collected, as the only other reference keeping hold of it is the child-instance itself (through the 'bound_this' functions).
I'm using underscore.js' 'bindAll' utility function (underscore.js#bindAll) that maps to the 'native_bind' function of chrome (ECMA Script wiki on bound_this)
Am I missing something obvious here and if so, could someone explain what's keeping these instances alive?
UPDATE:
In the meanwhile I tested the same application in chrominium (18.0.1025.168 (Developer Build 134367 Linux) Ubuntu 11.10) which does not show these dangling instances..
UPDATE 2:
Following Esailijas hint to provide a jsfiddle snippet, I created one (http://jsfiddle.net/8gSTR/1/) that mimics what I'm basically doing. Running this fiddle unfortunately does not show the misbehaviour I'm experiencing in my application. A heap-dump taken while 'a'-instances are still referenced looks kind of similar though despite of the reference from the window.o array which keeps the instances alive:
As such a reference is missing in my case (screenshot 1) I don't know what keeps chrome from freeing these instances...
UPDATE 3:
Followed loislos advice to enable hidden properties. The result (with one of the branches expanded) can be seen in the following screenshot but it does not take me any further.
Your suspicions that this is not an actual memory leak but weirdness with chrome is correct.
I recently ran across the same problem. IE11 will not show this.func = _.bind(this.func, this) as a memory leak while chrome will, even after you press the collect garbage button 100 times.
It will show it even after you run chrome with the jsflag nonsense and expose the underlying garbage collector and call gc 100 times.
A easy way to prove that it is in fact not a leak in chrome is to make a minor issue a major issue with the browser and force the engine to take action.
On the instance that has the bound function assigned to it assign a new property like this:
target.WhyAmILeaking = new Array(200000000).join("YOURNOT");
Do the three snapshot technique with chrome and you'll see that string present in the heap clocking in at around 214mb. Do whatever constructive action (the second snapshot) again and you'll see the heap go to 423mb or stay at 214mb. If it stays you're done as you proved the original 214mb has been collected. If it doesn't stay do your destructive action (third snapshot) and it'll go back to 214mb also proving the original got collected.
If it just stays at 423mb you sir or madam have a leak.
Oh and another group of poor souls that ran across the exact same situation: https://github.com/jashkenas/backbone/issues/2269#issuecomment-13610969
TL;DR; use IE 11 for detecting leaks.
I have referred this in EcmaScript, this term "bound this" with class,
Class methods have “bound this”, where this in the method body is always bound to the class instance from which the method was extracted, regardless of what this parameter is actually passed in to the method (the this parameter to the method is ignored).
Now here in your example there is no sample script given so can not be specific to question,
I have to say if this is not leak..
then with what ever object, class the script is bounded, it will not call garbage until the class/object exist as this function is bounded with the same object.. it will garbage collected only after its parent's(the object/class with which it is bounded) scope ends.
Now if circular reference when the task will finish it will come to end,>> this works like concept of Recursion(mind it concept, not same as).. so the end will start from the last call.. in reverse.. the inner most call(latest call) will be released first.. and so on
The code must be buggy as they must not bind and define function and reuse each time.. but if they are binding then also it should work fine and should not leak until the footprint goes out of the browser limit of memory pool.
I hope this will explain..
Are you triggering a "forced GC" using the developer tools? If that is the case and the objects then persist then the research above is of value.
If you are not triggering a GC via the developer tools, then do remember that the way the GC engine works is quite complicated and it has the concept of generational collection (using two generations).
http://www.html5rocks.com/en/tutorials/memory/effectivemanagement/#toc-v8-gc
It could simply be that you have not reached the required threshold to trigger a young generation GC, or that the objects have been tenured to the old Generation but that a old generation GC was never triggered.
Unfortunately the developer tools don't seem to show which generation was GC'd.