Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this garbage collected?

I'm sure something similar has been asked before, but the sheer number of similar questions that don't answer my question force me to ask for myself.

Say you have the following code:

(function() {
    "use strict";
    var somearray=[1, 2, 3];
    for(var i=0; i<somearray.length; i++) {
        //do something
        }
    function loop() {
        //do something repeatedly
        requestAnimationFrame(loop);
        }
    loop();
    })();

Since the variable i is defined in the same scope as a perpetual loop, does it continue to exist even if unused, waiting for the possibility that it may be used eventually? Or is JavaScript's (particularly Chrome's V8) garbage collector smart enough to determine whether it will be used or not?

I know that I can add console.log(i) to the loop somewhere and then i will continue to exist so long as it's referenced, but will it continue to exist unreferenced in a scope that continues to exist?


1 Answers

This not really a question about the garbage collector rather it is question about whether the closure is optimized. The closure optimizer of the execution environment might determine that the variables are not referenced (closed over) by the nested functions and then elide them from the closure environment. If that is the case, then they are candidates for collection. If the closure optimizer isn't run, or it determines i and somearray are referenced, or it cannot determine the lifetime of i and somearray, then they will not be collected as they are required by the closure environment.

A function has an implicit environment which includes all local variables in the enclosing function (and all functions enclosing it). This environment will capture any objects referenced by those variables. A closure optimizer statically analyzes the function to determine if the environment can be trimmed to elide the unreferenced variables. If the variables are elided from the environment they are candidates for collection as soon as the function invocation is concluded.

All modern JavaScript engines have a closure optimizer.

Some common things that might disable or limit the closure optimizer include being in a debug mode, using direct eval(), use of the arguments array, use of deprecated features such as caller.

As you can see, it clearly depends on what \\do something repeatedly does and in what context the code is executed in.

One way to ensure that they are not captured regardless of what \\do something repeatedly does is to ensure they are no longer in scope. An immediately executing function will do just that so changing your code to,

(function() {
  "use strict";
  (function() {
    var somearray=[1, 2, 3];
    for(var i=0; i<somearray.length; i++) {
      //do something
    }
   })();
  function loop() {
    //do something repeatedly
    requestAnimationFrame(loop);
  }
  loop();
})();

will ensure the array is not left hanging around in memory.

like image 100
chuckj Avatar answered Dec 05 '25 21:12

chuckj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!