This is definitely a memory leak. However, the memory consumption is so small and cannot be measured. I did some small changes to the source code.
- I put the entire code inside a loop to create the same scenario 100,000 times
- I increased the timer interval to about 16 minutes. This prevents browser from crashing
Here is the code:
for (var i = 0; i < 100000; i++) {
var buggyObject = {
callAgain: function() {
var ref = this;
var val = setTimeout(function() {
ref.callAgain();
}, 1000000); //16m
}
}
buggyObject.callAgain();
buggyObject = null;
}
My experiment:
I ran the code in Chrome Version 34.0.1847.116 m and captured memory changes using Developer Tools\Timeline.
As we can see in the picture, around 32 MB of memory has been consumed for running this code and after a while it's been decreased to about 30 MB and stayed unchanged (see #1).
After several garbage collecting attempts by Chrome (see #2) and one manual forced garbage collection by me (see #3, #4), the memory consumption remains unchanged.
There is no more buggyObject
and there is nothing we can do to release the memory. The only possible way is to close the browser.
What causes this?
The main reason for this behavior is the timer. Timer callback and its tied object, buggyObject will not be released until the timeout happens. In our case timer resets itself and runs forever and therefore its memory space will never be collected even if there is no reference to the original object.