Memory management is one of the most important responsibilities of any programming language runtime. There are programming languages such as C or C++, where the developers manually allocate and free memory. However, Javascript handles memory management automatically through a Garbage Collector (GC).
For most engineers, this process is invisible. However, understanding the garbage collector mechanism is very important. In this article we will see what JavaScript garbage collector is and how it works.
What is Garbage Collector?
A garbage collector is a mechanism that automatically frees memory that is no longer being used by a program.
When your JavaScript code creates objects, arrays, functions, etc, memory is allocated for them. Over time, some of these values become unreachable, meaning no part of the program can access them anymore.
The garbage collector identifies these unreachable values and reclaims their memory, making it available for future allocations.
In simple terms:
You create objects → memory is allocated
Objects become unused → memory becomes garbage
Garbage collector cleans it up
This process prevents programs from consuming more and more memory over time.
JS Memory Lifecycle
The JavaScript memory lifecycle generally follows three steps:
1. Memory Allocation
Memory is automatically allocated when values are created.
Example:
let user = {
name: “Razvan”,
age: 21
};
Here, memory is allocated for:
- the object
- its properties
- the string values
2. Memory Usage
The allocated memory is used by reading or writing values.
console.log(user.name);
user.age = 40;
During this phase, the program accesses stored data.
3. Memory Release
Once a value becomes unreachable, the garbage collector can free it.
user = null;
By removing the reference, the object may become eligible for garbage collection.
Reachability concept
Modern JavaScript garbage collectors rely on the concept of reachability.
An object is considered reachable if it can be accessed from the root of the program.
Typical roots include:
Global variables
Variables in the current call stack
Closures
References from other reachable objects
Example:
let user = {
profile: {
name: “John”
}
};
If user becomes null, both profile and name also become unreachable.
user = null;
At this point, the entire object tree can be cleaned by the garbage collector.
The Mark-and-Sweep Algorithm
The most widely used garbage collection algorithm in JavaScript engines is Mark-and-Sweep.
The process works in two phases:
1. Mark Phase
The garbage collector starts from the root objects and recursively marks all reachable objects.
Anything that can be accessed from the root is marked as alive.
2. Sweep Phase
After marking, the collector scans the memory heap and removes any object that was not marked.
These unmarked objects are considered garbage.
Root
│
├── Object A
│ └── Object B
│
└── Object C
Object D (unreachable)
In this scenario:
A, B, and C remain
D is removed
Note: Modern engines such as V8 (Chrome / NodeJS) implement more advanced strategies on top of Mark-and-Sweep. Some of these include generational / incremental / concurrent garbage collection.
Generational GC implies objects divided in 2 generations:
– young generation (newly created objects)
– old generation (objects that survive multiple GC cycles)
Most objects die young, so GC runs more frequently on the young generation, improving performance.
Incremental GC – instead of freezing the app to run GC all at once, incremental GC breaks the work into smaller chunks, reducing pauses.
Concurrent GC – some parts of the garbage collection process run in parallel with the main JavaScript thread, further reducing blocking time.
In modern JS development, having a basic understanding of the garbage collector is an important part of writing cleaner and more performant code.