Understanding JavaScript Memory Management using Garbage Collection
The primary goal of memory management is to offer the system dynamically allocated memory when requested for and later free that memory containing objects that are no longer in use. Languages like C, C++ have primitive functions for memory allocation like malloc()
where some high level language computer architectures ( like JavaScript ) include garbage collector to do this job. It tracks the memory allocation and identifies if the allocated memory is no longer used, it is then freed automatically. But such algorithms cannot completely decide if the memory is required or not. Therefore, it is very important for the programmer to understand and decide if a particular piece of code needs memory or not. Let’s understand how does the garbage collection works in JavaScript:
Garbage Collection
The JavaScript Engine’s Garbage collector basically looks out for unreachable objects which are removed from the memory. There are two garbage collection algorithms that I would like to explain which are as follows:
- Reference-counting garbage collection
- Mark-and-sweep algorithm
Reference-counting garbage collection
This is a naïve garbage collection algorithm. This algorithm looks out for those objects which have no references left. An object becomes eligible for garbage collection if it has no references attached to it.
var obj1 = { property1: { subproperty1: 20 }
};
Let’s create an object as shown in the above example to understand this algorithm. Here obj1
has an object in which its property1
holds further one object. As the obj1
has the reference to the object, nothing is eligible for garbage collection.
var obj2 = obj1;obj1 = "some random text"
Now, obj2
also has the reference to the same object that was referred by obj1
but later obj1
was updated with "some random text"
which lead to obj2
having the unique reference to that object.
var obj_property1 = obj2.property1;
Now obj_property1
refers to obj2.property1
which also holds an object. Therefore that object has two references which are as follows:
- As a property of
obj2
- In the variable
obj_property1
obj2 = "some random text"
obj2
has been unreferenced by updating "some random text"
. Therefore it might seem that the object it held before has no references to it and can be garbage collected. But that might be wrong to say as obj_property1
has the reference of obj2.property1
. Therefore it won’t be garbage collected.
obj_property1 = null;
Now the object which was originally in obj1
has no references left as we removed the reference from obj_property1
. So now it can be garbage collected.
Where does this algorithm fail?
function example() { var obj1 = { property1 : { subproperty1: 20 } }; var obj2 = obj1.property1; obj2.property1 = obj1; return 'some random text'}example();
Here the reference counting algorithm does not remove obj1
and obj2
from the memory after the function call, since both the objects are referenced by each other.
Mark-and-Sweep Algorithm
This algorithm looks out for objects which are unreachable from the root which is the JavaScript’s global object. This algorithm overcomes the limitations of Reference-counting algorithm. As an object with no references would be unreachable but not vice-versa.
var obj1 = { property1: 35}
As shown above, we can see how the created object obj1
becomes reachable from the ROOT.
obj1 = null
Now when we set the value of obj1
to null
the object is no more reachable from the ROOT and hence it is garbage collected.
This algorithm starts from the root and traverses down to all other objects while marking them . It further traverses through the traversed objects and marks them. This process continues till the algorithm has no child nodes or any path left to traverse while marking all the nodes that have been traversed. Now the garbage collector ignores all the reachable objects as they were marked while traversing. So all the objects that were not marked were clearly unreachable to the root which makes them eligible for garbage collection and later the memory is freed by removing those objects. Let’s try and understand by looking at the following instance:
As shown above, this is how an object structure would look like. We can notice the objects which are not reachable from the root but let’s try to understand how would Mark-and-Sweep algorithm work in this case.
Algorithm starts marking the objects which it traverses starting from the root. In the above image we can notice the green circles which are marked on the objects. So that it identifies the objects as reachable from the root.
The objects which are not marked are unreachable from the root. Therefore, they are garbage collected.
Limitation
Objects have to be made explicitly unreachable.
Since 2012, JavaScript Engine’s have adapted this algorithm over Reference-counting garbage collection.
Thanks for reading.