What is Garbage Collection?

Garbage collection (GC) is the process of automatically freeing up memory that is no longer being used by a program. In JavaScript, when you declare variables, objects, or functions, memory is allocated to store them. When these are no longer needed, the garbage collector identifies and clears them from memory.

Key Point: JavaScript is a high-level language with automatic memory management. You don’t manually allocate or free memory – the JavaScript engine handles this for you through garbage collection.

Memory Lifecycle in JavaScript

The memory lifecycle in JavaScript consists of three phases:

Phase Description Example
Allocation Memory is allocated when you declare variables, create objects or functions let obj = { name: "John" };
Usage Reading and writing to allocated memory console.log(obj.name);
Release Freeing memory when it’s no longer needed (handled by GC) obj = null; // Makes object eligible for GC

Reachability: The Key Concept

The main concept behind garbage collection is reachability. Values that are accessible or usable are called “reachable” and are kept in memory.

Understanding Reachability

// Initially, the object is reachable via the 'obj' reference
let obj = { name: "Orange" };

// Now we have two references to the same object
let obj2 = obj;

// Removing one reference - the object is still reachable via obj2
obj = null;

// Removing the last reference - the object is now unreachable
obj2 = null;

// The { name: "Orange" } object is now eligible for garbage collection

obj → {name: “Orange”}

Object is reachable

obj2 → {name: “Orange”}
obj → null

Object still reachable via obj2

{name: “Orange”}
obj → null
obj2 → null

Object is unreachable (eligible for GC)

The Mark-and-Sweep Algorithm

Modern JavaScript engines use the mark-and-sweep algorithm for garbage collection. This algorithm works in two phases:

  1. Mark: The garbage collector starts from “roots” (global variables) and marks all references that are reachable.
  2. Sweep: The garbage collector sweeps through memory and removes objects that weren’t marked (unreachable).

Mark-and-Sweep Process

// Global object (root)
let globalObj = {
    refA: {
        name: "A"
    }
};

// Another reference
let refB = {
    name: "B",
    refC: {
        name: "C"
    }
};

// Creating a circular reference (not a problem for mark-and-sweep)
globalObj.refA.refB = refB;
refB.refC.refA = globalObj.refA;

// Removing references
refB = null;

// The mark-and-sweep algorithm will correctly identify
// which objects are still reachable from the root (globalObj)

Memory Leaks in JavaScript

Despite automatic garbage collection, memory leaks can still occur in JavaScript. Common causes include:

Cause Description Prevention
Accidental Global Variables Variables declared without var/let/const become global Always declare variables properly
Forgotten Timers/Callbacks setInterval or event listeners that aren’t cleaned up Clear intervals and remove event listeners
Closures Holding references to large objects unnecessarily Be mindful of what closures capture
Detached DOM Elements DOM elements removed from DOM but referenced in JavaScript Nullify references to removed DOM elements

Circular Reference Example (Historical)

// In older browsers, circular references could cause memory leaks
function createLeak() {
    let teacher = new Teacher();
    let student = new Student();
    
    // Circular reference
    teacher.student = student;
    student.teacher = teacher;
    
    return teacher;
}

// Modern garbage collectors (mark-and-sweep) handle this correctly
// The objects will be collected when no longer reachable

Best Practices for Memory Management

  • Use let and const instead of var for block scoping
  • Avoid creating unnecessary global variables
  • Nullify references to large objects when no longer needed
  • Clean up event listeners and timers when done
  • Be cautious with closures that capture large objects
  • Use developer tools to profile memory usage