JavaScript Garbage Collection

In this chapter, we are going to see how JavaScript manages its memory. JavaScript is a unique language, it is capable of automatically allocating memory once objects are created and freeing it when they are not used anymore. In contrast, low-level languages require manual determination at what point in the program that allocated memory is not needed anymore and free it. So, let’s see what happens in a high-level language such as JavaScript when you don’t need anything anymore. How JavaScript engine finds it out and cleans it up.

The Primary Concept

Reachability is the primary concept of JavaScript memory management. The values that are accessible and usable are known as reachable. Below you will find the set of base reachable values:

The values above are called the roots.

Other values are known as reachable once they are reachable from a root by a chain of references or a single reference.

Consider an object inside a local variable. If that object has a property that references another object, that object is called reachable. The references are also reachable.

In JavaScript, there exists a background process, called a garbage collector. It is capable of monitoring all objects and removing the ones that have become unreachable.

For a better perception, check out the example below:

// book has a reference to the object
let book = {
  name: "Javascript"
};
console.log(book);

As you can see, the object reference is depicted by the arrow. The global variable "book" is referencing the object. The "name" property itself stores a primitive.

In case the book value is overwritten, the reference will be lost, as shown below:

// book has a reference to the object
let book = {
  name: "Javascript"
};
book = null;
console.log(book);

So, the object becomes unreachable. The garbage collector junks the data, freeing the memory.

A Case of Two References

In this section, let’ consider that the reference was copied from the book to language like this:

// book has a reference to the object
let book = {
  name: "Javascript"
};
let language = book;
console.log(language);

Now, doing the same will look like this:

// book has a reference to the object
let book = {
  name: "Javascript"
};
let language = book;
console.log(language);
book = null;
console.log(book);

The object will still be reachable via the language global variable. It’s in the memory. After overwriting the language, it can be deleted.

Internal Algorithms

The main algorithm of the garbage collection is known as “mark-and-sweep”. Regularly some garbage collection steps are performed. Here they are:

  • The collector takes roots and marks, remembering them.
  • Afterward, it visits and marks all the references from them.
  • The next step is visiting the marked objects, marking their references. It is not possible to visit the same object twice, as all the visited objects are remembered.
  • The process goes on until every reachable reference is visited.
  • All the objects except for the market objects are deleted.

And, finally, the objects that couldn’t be visited during the process above, are considered unreachable and are going to be removed.

So, the described process of the garbage collection works properly. But, JavaScript includes different optimizations for making them work even better and faster. Among those optimizations are Generational collection, Incremental collection, and Idle-time collection.

Summary

Garbage collection is a process that is implemented automatically. It can’t be forced or prevented anyhow.

Objects can be retained in memory while they are reachable.

It’s essential to know that being referenced is not similar to being reachable. Advanced algorithms of garbage collection are performed by modern engines.




Do you find this helpful?

Related articles