Thursday, March 28, 2024

Overview of Garbage Collection in JavaScript

JavaScript Garbage Collection Tutorial

Garbage collection and memory management in JavaScript are slightly unfamiliar topics for most developers, as we do not usually perform any memory management operations explicitly in the majority of programming languages. However, it is recommended (and always beneficial) to know how the memory management cycle works and how the occupied resources are freed when they are no longer in use.

Memory Allocation in JavaScript

In low-level programming languages like C, developers need to take care of memory. They have to manually allocate or release memory using functions like calloc(), malloc(), realloc(), and free(). In high-level languages like JavaScript and Java, however, we do not need to manually allocate or deallocate memory; instead, it is done by the language itself.

In JavaScript, when you create a new object, you do not need any special method to allocate memory for that object. Similarly, when you want to destroy that object, you do not need to explicitly call any special method to free up the memory. JavaScript is there for you to handle memory allocation and deallocation all on its own.

The process of memory management in almost all high level languages is automatic, but that does not mean that the developers are free of worries with regards to memory management. The way you have coded something has a significant impact on the allocation of memory. If the code you wrote is of poor quality, it may lead to memory leakage and eventually the application performance might suffer. So, becoming aware of memory management techniques and garbage collection is really important.

Before diving into the garbage collection, we must first take a look at how memory is managed.

Read: HTML, CSS, and JavaScript Tool and Libraries

What is the JavaScript Memory Lifecycle

The memory lifecycle describes how memory is managed. The process is divided into three steps. First, you need memory to allocate. Whenever you create a new variable and assign a value to it, it will allocate the memory for that variable.

The second step is to utilize that allocated memory for tasks such as reading or writing operations. You may want to read some object’s property or you modify them in some way.

The third step is to deallocate memory for that object. You may want to free up the memory when that variable or object is no longer needed. The third step is critical because if you do not release the occupied memory of your program, it will consume more and more memory from your application and result in your application crashing.

Deallocation of memory is sometimes a difficult task in the memory cycle process, regardless of whether it is done manually or gets handled by the programming language itself.

JavaScript Garbage Collection Examples

A high-level, modern programming language such as JavaScript takes care of all of the steps involving memory management – from allocating resources all the way to releasing them. But how is the memory released once it is no longer needed? Our next section depicts releasing the allocated resources through a process called garbage collection.

How Garbage Collection Works in JavaScript

As we have already discussed, the third step in memory management is a difficult process. How does JavaScript know what memory should be released? What tools are used by the garbage collector to release those resources?

There are a few algorithms and tools the garbage collector uses to figure this out. Let’s take a look at some of those strategies in the next section.

Read: Asynchronous Programming in JavaScript

Reference Counting Garbage Collector Strategy

This garbage collection strategy is used for pointing out resources that no longer have any references. Consider the following code snippet:

const obj = {
  name: ‘Bob’,
  country: 'United States',
};
 
obj = 'You are reading the article on Garbage Collection';

Initially, the obj object is holding some property attributes. Later on, the developer decided to change the obj object to hold a primitive value. So now, the first obj object does not hold any references pointing to it, which makes it ready to be claimed for garbage collection.

But it is not as simple as that.

There is a lesser known strategy you should be aware of, called circular dependency. The developer probably never thought of it before, because JavaScript handles it for you under the hood.

Think of a situation where two objects are referencing each other. In that case, the garbage collector would not be able to decide which one to remove from memory because each one has at least one reference to another one.

To get a better understanding, consider the following JavaScript code snippet:

var obj = 
{ 
a: 
{ 
b: ‘Hello’ 
} 
};
obj = 15.6;
 
function callMe() { 
var obj = {}; 
var obj2 = {}; 
obj.a = obj2; 
obj2.a = obj; 
return obj; 
} 
callMe();

The above code shows that the object obj is referencing obj2 and obj2 is referencing obj. This creates a cycle.

After the scope is moved out of the function callMe(), the garbage collector will not be able to free the memory occupied by these two objects because they hold references to each other. This causes the program to leak memory.

To overcome this situation, JavaScript has another strategy developers can take advantage of, as detailed in the next section.

The JavaScript mark-and-sweep Algorithm

The mark-and-sweep algorithm is a famous algorithm used for garbage collection and it is far better than the algorithm in the previous section. It works on the principle of determining whether the object can be reached from the root. In JavaScript, you can think of root as a window object in a Chrome browser; think of a global object if you are on a Node.js app.

This strategy works as follows:

First, it marks all the root objects. Next, it will visit all the references that can be reached from these root objects. Again, it revisits the marked objects and marks their references. This process of visiting and marking continues until all the reachable references are visited.

The garbage collector can now identify which objects are marked and which are not. So, the objects which are not marked (they are called unreachable objects) are selected for garbage collection and finally get removed from memory.

Read: OOP in JavaScript with Classes

Final Thoughts on Garbage Collection in JavaScript

This web developer tutorial was just an overview of the garbage collection strategies used in JavaScript. The subject is far more complex and cannot be explained in a single article. I recommend developer learn more about it through the MDN doc.

The way in which a developer codes also impacts how much memory will be allocated. That is why it is important to focus on writing code with best practices and get familiar with the strategies of garbage collection and how they free up the resources whenever needed. There are several tools and methods out there in the market which can help you in analyzing memory leaks and other performance issues in your program as well.

Tariq Siddiqui
Tariq Siddiqui
A graduate in MS Computer Applications and a Web Developer from India with diverse skills across multiple Web development technologies. Enjoys writing about any tech topic, including programming, algorithms and cloud computing. Traveling and playing video games are the hobbies that interest me most.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Popular Articles

Featured