google / google/CodeCity

Closures should not prevent inaccessible data from being collected

Open
#148 0 comments 0 reactions 0 assignees View on GitHub
enhancement server
Dominant language
JavaScript
Stars
198
Forks
38
PR merge metrics
No merged PRs in 30d

Description

At the moment, the following code will prevent `a`, `b` and `c` from being garbage collected even though only `a` is ever accessible:

```JS
function foo(a, b, c) {
return function() {return a;};
}

var longLived = foo('a', 'b', 'c');
```

Because of `eval` we can't always know which closed-over local variables are accessible:

```JS
function foo(a, b, c, src) {
return function() {return eval(src);};
}
var f = foo('alpha', 'bravo', 'charlie');
var a = f('a'); // a === 'alpha'
```

But in the absence of direct calls to `eval` in the body of the inner function we can—and should.

Note that things get more complicated when separate closures created share variables, e.g:

```JS
function foo(a, b, c) {
return [function ab() {return a + b;},
function bc() {return b + c;},
function ca() {return c + a;}];
}
```
Ideally if only `ab` is retained `c` should be garbage collected—but in practice implementing this for arbitrary combinations may be impractical ([and V8 doesn't try](https://stackoverflow.com/questions/38838071/closure-memory-leak-of-unused-variables?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)).

Related reading:
* [Closure memory leak of unused variables
](https://stackoverflow.com/questions/38838071/closure-memory-leak-of-unused-variables?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
* Slide 36 ("Unintended retention – runtime black magic") of [the tc39 Weak References for EcmaScript proposal](https://github.com/tc39/proposal-weakrefs/blob/master/specs/Weak%20References%20for%20EcmaScript.pdf).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.