Closure memory leak of unused variables

After you call a() your fstore has reference to created function () => void only. After a() returns, its scope vars will be deleted. It means that no vars has reference to your new Array(1000000).join('*') and it will be garbage collected. It will be collected the same way if you uncomment unused function because it will deleted too. There are no leaks in your code.


The compiler can examine the code of the returned function to see which free variables it references, and only those variables need to be saved in the closure, not the entire LexicalEnvironment. You can see this by examining the closure in the Javascript debugger.

function a() {
  let big = new Array(1000000).join('*');
  let small = "abc"; // is accessed
  return (x) => small + x;
}

fun = a();
console.dir(fun);

function b() {
    let big = "pretend this is a really long string";
    function unused() { big; }
    return () => void 0;
}

fun = b();
console.dir(fun);

When you expand the first function in the debugger, you'll see small in the Closure property, but not big. Unfortunately, the Chrome compiler doesn't seem to be clever enough to detect when the variable is referenced in an unused function that isn't returned, so it doesn't need to be saved, so we get a leak in b().

enter image description here

Any data that isn't saved in the closure becomes garbage and can be collected, so it won't leak.

Tags:

Javascript