Memory management

Allocate and deallocate memory

When a program is executed, computer memory (RAM) to store values need to be allocated, and memory needs to be deallocated for reuse when no longer needed. This dynamic process of allocating and releasing memory is known as memory management.

Memory management is essential to prevent memory leaks, exhausting available memory as an application runs. Low-level programming languages require explicit memory management, i.e., manually allocating and deallocating memory. High-level languages, like JavaScript, generally utilize a form of automatic memory management. This does not mean that JavaScript programmers never need to take memory management into account.

In JavaScript memory allocation is performed automatically. JavaScript implicitly allocates memory when values are initially declared. JavaScript also automatically releases memory for reuse when values are no longer needed. But this automatic deallocation process is only an approximation. The difficult aspect of deallocation is determining when the allocated memory is no longer needed. The automatic process of deallocation is known as garbage collection.

Garbage collection

Suppose we declare a variable and initialize it with a new object. Right after that we override the variable with an other value. The original object and its own properties still exist in memory, but there is no reference to them anymore. The original object and its own properties cannot be used anymore. Reading and writing them in allocated memory is no longer possible since they became unreachable. Their allocated memory can and should be released for reuse; they are ready for garbage collection.


let myObject = { a: 1 };

myObject = null; // myObject is overridden, no reference to the original object still exist.

Of coerce the object and/or own properties may have multiple references from multiple variables, properties or parameters. Allocated memory should only be released for reuse after all references are lost.

A reference may break due to overriding a variable, but also local variables or parameters may loose all references if they go out of scope, e.g., after a function call has completed.

In JavaScript primitives are or of the value data type; the value is stored in the variable. Overriding a primitive does not break a reference, it overwrites, it destroys the actual value. Objects however, are of the reference data type. Overriding a variable referencing an object does leave the original object without references, lost in memory.

A problem may occur when values reference one another and all other references are lost. They form a cycle. They still reference each other, yet they are unreachable and their allocated memory should be released for reuse. Memory management in modern JavaScript engines uses algorithms that do not cause problems when circular references occur.

Mark-and-sweep garbage collector

The mark-and-sweep garbage collector periodically start from a set of roots, to find all reachable values and garbage collect all non-reachable values. The roots are values that are obviously reachable, like the currently executing function and its local variables and parameters, and values available in global scope. Find all values that are referenced from these roots, then all values referenced from these, etc. This way the garbage collector finds all reachable values.

With mark-and-sweep garbage collecting, cycles are no longer a problem. Having zero references is not the criterion, but being non-reachable is the reason for garbage collection. Two values that only reference each other are unreachable from the roots.

The mark-and-sweep garbage collector is the original basic algorithm of tracing garbage collection. All modern JavaScript engines use tracing garbage collection, although there are implementation differences between different engines.

JavaScript does not provide a way to manually control garbage collection; it is not possible to programmatically trigger or stop garbage collection or to control what memory is released.

Objects aiding memory management

Although the garbage collector cannot be directly controlled in JavaScript, the language offers a few data structures that can indirectly be used to manage memory usage. Most notable are WeakMaps and WeakSets, which will be explained in the next chapter.