I'm fairly sure the issue being illustrated here is due to an optimization in how closure scopes are created, which I don't think any of the answers mention (yet). Can't remember where I saw this, but there's a blog-post somewhere in the wild that explains. Slap me if I'm wrong.<p><pre><code> // scope 1
var someClass = function() {};
function f() {
// scope 1, 2
var some = new someClass();
function unreachable() { some; /* scope 1, 2, 3 */ }
return function() { /* scope 1, 2, 4 */ };
}
window.f_ = f();
</code></pre>
Basically, any closures created within scope 2 will share the same parent scope in its scope chain rather than each closure having its own parent. That means any variable in scope 2 that's captured by a child closure (3 or 4) will be included in the other child scopes.<p>In this case, `some` is captured in `unreachable()`, thus it's going to be included in the returned function as well. The returned function is then retained with `window.f_`, and that's the leak.<p>EDIT: for clarity. EDIT2: not the original article I read, but this does cover it: <a href="http://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak" rel="nofollow">http://www.meteor.com/blog/2013/08/13/an-interesting-kind-of...</a>
The author wrote a really short code snippet that demonstrates the problem:<p><pre><code> function f() {
var some = [];
while(some.length < 1e6) {
some.push(some.length);
}
function g() { some; } //removing this fixes a massive memory leak
return function() {}; //or removing this
}
</code></pre>
If you keep a reference to the results of calling this function, it will keep a reference to the "some" variable, even though it is not needed.<p>He created a page that demonstrates the problem here:<p><a href="https://s3.amazonaws.com/chromebugs/memory.html" rel="nofollow">https://s3.amazonaws.com/chromebugs/memory.html</a>
Unfortunately, this behavior is common across all major browsers. There is a Chromium bug for it (<a href="http://crbug.com/315190" rel="nofollow">http://crbug.com/315190</a>), but no responses as of yet.