Search code examples
javascriptgarbage-collectionv8spidermonkey

When and How JavaScript garbage collector works


I did read few articles like this on MDN and this one I got the idea of how GC happens in JavaScript

I still don't understand things like

a) When does Garbage collector kicks in ( it gets called after some interval or some conditions have to met) ?

b) Who is responsible for Garbage collection ( it's part of JavaScript engine or browser/Node ) ?

c) runs on main thread or separate thread ?

d) which one of the following have higher peak memory usage ?

// first-case
// variables will be unreachable after each cycle

(function() {
  for (let i = 0; i < 10000; i++) {
    let name = 'this is name' + i;
    let index = i;
  }
})()
// second-case
// creating variable once

(function() {
  let i, name, index;

  for (i = 0; i < 10000; i++) {
    name = 'this is name' + i;
    index = i;
  }
})()

Solution

  • V8 developer here. The short answer is: it's complicated. In particular, different JavaScript engines, and different versions of the same engine, will do things differently.

    To address your specific questions:

    a) When does Garbage collector kicks in ( it gets called after some interval or some conditions have to met) ?

    Depends. Probably both. Modern garbage collectors often are generational: they have a relatively small "young generation", which gets collected whenever it is full. Additionally they have a much larger "old generation", where they typically do their work in many small steps, so as to never interrupt execution for too long. One common way to trigger such a small step is when N bytes (or objects) have been allocated since the last step. Another way, especially in modern tabbed browsers, is to trigger GC activity when a tab is inactive or in the background. There may well be additional triggers beyond these two.

    b) Who is responsible for Garbage collection ( it's part of JavaScript engine or browser/Node ) ?

    The garbage collector is part of the JavaScript engine. That said, it must have certain interactions with the respective embedder to deal with embedder-managed objects (e.g. DOM nodes) whose lifetime is tied to JavaScript objects in one way or another.

    c) runs on main thread or separate thread ?

    Depends. In a modern implementation, typically both: some work happens in the background (in one or more threads), some steps are more efficient to do on the main thread.

    d) which one of the following have higher peak memory usage ?

    These two snippets will (probably) have the same peak memory usage: neither of them ever lets objects allocated by more than one iteration be reachable at the same time.


    Edit: if you want to read more about recent GC-related work that V8 has been doing, you can find a series of blog posts here: https://v8.dev/blog/tags/memory