i'd understand under circumstances variables no further used stored in closures , lead memory leaks. preferred outcome "there none", doesn't seem case.
from understand, once function declared inside function, internal [[scope]] assigned lexicalenvironment of encapsulating function. lexicalenvironment has reference local variables , entire scope chain @ point. includes all free variables function access (from understood of lostechies, javascript closures explained).
here first issue arises: should mean all variables can reached long function lives. e.g. following should leak:
function a() { let big = new array(1000000).join('*'); //never accessed //function unused() { big; } return () => void 0; } let fstore = []; function doesthisleak() { for(let = 0; < 100; i++) fstore.push(a()); } doesthisleak();
this luckily doesn't seem case on firefox. i've received several explanations why doesn't leak, "the jitter smart" "lexicalenvironment record type means gc can collect unused variables". still don't know whether either correct, whether doesn't leak on modern runtimes , why.
after further research, found auth0, 4 types of leaks in javascript (sadly, there appears no html id jump to, relevant part "4: closures") shows way trick whatever smart thing collecting unused variables. in above snippet, when uncommenting "unused" function, not see ram usage ever going down again (it noted gc did not run other reasons. however, far, assuming leaks. got told limited firefox, appeared produce similar behavior in chrome)
this example (in case believe does), shows unused variables can leak due function declaration in same scope.
to conclude problems:
- what reason for, in above snippet, "big" getting collected (when "unused" commented) , happen on modern runtimes?
- assuming example "unused" function not commented leaks, best practices avoid such accidental leaks? there more? got suggestion of null'ing local variables not further used @ end of functions, however, seems absurdly ugly. fear using temporary variables pre-calculations , accidentally leaking.
ps: quite hard make question has not been asked in jungle of questions memory leaks closures.
the compiler can examine code of returned function see free variables references, , variables need saved in closure, not entire lexicalenvironment. can see examining closure in javascript debugger.
function a() { let big = new array(1000000).join('*'); let small = "abc"; // accessed return (x) => small + x; } fun = a(); console.dir(fun); function b() { let big = "pretend long string"; function unused() { big; } return () => void 0; } fun = b(); console.dir(fun);
when expand first function in debugger, you'll see small
in closure
property, not big
. unfortunately, chrome compiler doesn't seem clever enough detect when variable referenced in unused function isn't returned, doesn't need saved, leak in b()
.
any data isn't saved in closure becomes garbage , can collected, won't leak.
Comments
Post a Comment