Closures should not prevent inaccessible data from being collected
- 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
Assessment
This issue has not been assessed yet.