Search code examples
javascriptmemory-leaksclosures

Lexical environment and memory in self-scheduling functions


Does this kind of code have a memory leak:

let n = 0;

function foo() {
    const str = '...long string' + (++n);
    setImmediate(() => {
        console.log('str=' + str);
        foo();
    });
}

foo();

I'm asking because, as I understand, each function's lexical environment has a pointer to the lexical environment in which the function was created. So it seems like in the above we will have a growing chain of lexical environments.

If so, what is the pattern to get around this problem? If not, what is the error with the reasoning above?


Solution

  • each function's lexical environment has a pointer to the lexical environment in which the function was created.

    Yes.

    So it seems like in the above we will have a growing chain of lexical environments.

    No. foo has a pointer to the outer lexical environment in which n is declared. Each of the arrow functions that are getting created is having a pointer to the lexical environment in which str is declared (which in turn is linked to the outer one).

    But calling foo() again does not grow the chain, it only creates a new environment for that function call, linked to the outer environment (with n) and declares a new str in it.

    Won't the active one have a pointer to the lexical environment of the one that previously ran so it can e.g. access local variables declared there?

    No. The pointer that is used when the function is called only depends on where the function was defined, not what was active before.