All topics
Performanceintermediate

Memory Management and Garbage Collection

How JavaScript automatically allocates and reclaims memory, and the mark-and-sweep algorithm that decides what can be safely freed.

JavaScript allocates and frees memory for you. The collector frees anything unreachable.

Garbage collection is like a library periodically checking which books are still connected to an active reader's request chain (checked out, or on hold for someone) versus books sitting unclaimed with literally nobody able to request them anymore — the library doesn't wait for you to manually return every book; it just periodically clears out anything nobody could possibly still be holding onto or reaching.

Key Concepts

1
Reachability, not reference counting. Starting from the roots — globals, the current stack, closures in use — the collector marks everything it can reach and sweeps the rest.
2
    let a = { name: 'x' };
    a = null;            // the object is now unreachable -> collectable
3
Which is why cycles are not a problem in modern engines:
4
    const x = {}, y = {};
    x.other = y; y.other = x;      // they reference each other
    // both unreachable from a root -> both collected
5
Reference counting cannot free that; mark-and-sweep can.
6
Generational collection is the optimisation that makes it fast: most objects die young, so the nursery is collected often and cheaply, and survivors are promoted to an older space collected rarely.
7
The four leaks worth knowing.Listeners never removed. The handler keeps its closure alive, which keeps the element alive:
8
    el.addEventListener('click', handler);
    el.remove();                    // the listener still holds it
    el.removeEventListener('click', handler);
9
Timers. A setInterval never cleared keeps running and keeps its closure alive.
setInterval
10
Detached DOM nodes. An element removed from the page but still referenced by a variable or an array is still in memory, along with all its children.
11
Growing caches. A Map used as a cache with no eviction grows forever. A WeakMap keyed by object lets entries disappear when the key does — which is exactly what a cache keyed by DOM node or component wants.
MapWeakMap
12
Finding a leak. Chrome DevTools Memory: take a heap snapshot, do the thing, take another, compare. The comparison view shows what was allocated and not released, and the retainer path shows what is holding it.
13
The pattern to look for is a number that rises with every cycle of an action and never falls.
14
What not to do. Do not try to help the collector — assigning null to locals, or calling suggested collection — makes no measurable difference. Fix the references that should not exist instead.
null
15
What the interviewer is probing.1. "How does JavaScript decide what to collect?" Probing: the model. Stalls: "Reference counting." Moves up: reachability from the roots — mark and sweep — which is why cycles are collected but a referenced-but-unused object is not.
16
2. "Name three common leak sources." Probing: practical knowledge. Stalls: "Big objects." Moves up: listeners never removed, timers never cleared, and closures or caches holding references longer than needed — plus detached DOM nodes still referenced.
17
3. "What is a detached DOM node?" Probing: the specific leak. Stalls: "A removed element." Moves up: an element removed from the document but still referenced by script, so neither it nor its subtree can be collected.
18
4. "How would you find a leak?" Probing: the method. Stalls: "Guess." Moves up: heap snapshots before and after a repeated action, comparing retained size and following the retainer path.