How JavaScript closures are garbage collected(stackoverflow.com) |
How JavaScript closures are garbage collected(stackoverflow.com) |
// 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();
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.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.
EDIT: for clarity. EDIT2: not the original article I read, but this does cover it: http://www.meteor.com/blog/2013/08/13/an-interesting-kind-of...
Well, the typical way that closures are implemented is that every function object has a link to a dictionary-style object representing its lexical scope. If both functions defined inside replaceThing actually used originalThing, it would be important that they both get the same object, even if originalThing gets assigned to over and over, so both functions share the same lexical environment.
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
}
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.He created a page that demonstrates the problem here:
IE used to not GC cyclical JS/DOM references. Google Chrome is doing a massive rework of DOM garbage collection with Oilpan.
You are right that it is not a trivial change, but there is nothing technically infeasible about GC'ing per closure. I think it is worth it, just as it was worth it for IE to have smarter GC.
good question by the way