How Memory management and Garbage collector works in JavaScript?
By: Upender Bhardwaj
Tags: Garbage Collection, JavaScript, Algorithms, Web Development, Browsers

JavaScript Engine allocates memory when we declare a variable or function or any data structure that can hold some value. If value inside that variable grows dynamically, JS engine increases its allocated memory size dynamically.

In JavaScript, memory is allocated and reclaimed automatically. It uses automatic memory management known as garbage collection (GC).

The garbage collector monitors memory allocation and determines when an allocated memory space is not needed and recollects it. This automatic process works on principle of approximation as it cannot determine whether or not a specific piece of memory is still needed.

Garbage collection

To deal with this problem GC implemented a restriction of a solution to the general problem. We will now discuss some important topics to better understand the GC fundamentals.

References

The main concept that garbage collection algorithms rely on is the concept of reference. Within the context of memory management, an object is said to reference another object if the former has access to the latter (either implicitly or explicitly). For instance, a JavaScript object has a reference to its prototype (implicit reference) and to its properties values (explicit reference).

In this context, the notion of an “object” is extended to something broader than regular JavaScript objects and also contain function scopes (or the global lexical scope).

Reference-counting

This is the most naive garbage collection algorithm. This algorithm reduces the problem from determining whether or not an object is still needed to determining if an object still has any other objects referencing it. An object is said to be “garbage”, or collectible if there are zero references pointing to it.

Example

var x = {

a: {

b: 2

}

};

// 2 objects are created. One is referenced by the other as one of its properties.

// The other is referenced by virtue of being assigned to the 'x' variable.

// Obviously, none can be garbage-collected.

var y = x; // The 'y' variable is the second thing that has a reference to the object. x = 1; // Now, the object that was originally in 'x' has a unique reference

// embodied by the 'y' variable. var z = y.a; // Reference to 'a' property of the object.

// This object now has 2 references: one as a property,

// the other as the 'z' variable. y = 'mozilla'; // The object that was originally in 'x' has now zero

// references to it. It can be garbage-collected.

// However its 'a' property is still referenced by

// the 'z' variable, so it cannot be freed. z = null; // The 'a' property of the object originally in x

// has zero references to it. It can be garbage collected.

Limitation: Circular references

There is a limitation when it comes to circular references. In the following example, two objects are created with properties that reference one another, thus creating a cycle. They will go out of scope after the function call has completed. At that point they become unneeded and their allocated memory should be reclaimed. However, the reference-counting algorithm will not consider them reclaimable since each of the two objects has at least one reference pointing to them, resulting in neither of them being marked for garbage collection. Circular references are a common cause of memory leaks.

Look at the example to make things clear.

function f() {

var x = {};

var y = {};

x.a = y; // x references y

y.a = x; // y references x return 'sate sate sate';

} f();

Mark-and-sweep algorithm

This algorithm reduces the definition of “an object is no longer needed” to “an object is unreachable”.

This algorithm assumes the knowledge of a set of objects called roots. In JavaScript, the root is the global object. Periodically, the garbage collector will start from these roots, find all objects that are referenced from these roots, then all objects referenced from these, etc. Starting from the roots, the garbage collector will thus find all reachable objects and collect all non-reachable objects.

This algorithm is an improvement over the previous one since an object having zero references is effectively unreachable. The opposite does not hold true as we have seen with circular references.

Cycles are no longer a problem

In the first example above, after the function call returns, the two objects are no longer referenced by any resource that is reachable from the global object. Consequently, they will be found unreachable by the garbage collector and have their allocated memory reclaimed.

Limitation: Releasing memory manually

Sometimes, manual control over release of memory is much easier.

As of 2019, it is not possible to explicitly or programmatically trigger garbage collection in JavaScript.

// The End

References:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management