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 manages memory automatically through garbage collection, meaning developers don't manually allocate and free memory the way they would in a language like C, but understanding roughly how the garbage collector decides what to reclaim is still essential for avoiding memory leaks and for reasoning about performance in long-running applications like single-page apps or Node servers.

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
Memory is allocated automatically whenever a value is created — a variable declaration, an object literal, a function call's local variables and arguments. The garbage collector's job is figuring out which previously-allocated memory is no longer reachable from anywhere the running program could still access, and reclaiming it. Modern engines use a 'mark-and-sweep' algorithm as their core strategy: starting from a set of 'roots' (global variables, currently executing functions' local variables), the collector marks every object reachable by following references from those roots, then sweeps away (frees) anything left unmarked, on the assumption that if nothing reachable references a piece of memory anymore, the program can never access it again anyway, so it's safe to reclaim.
2
This reachability-based approach is why circular references between two objects don't cause a memory leak by themselves in modern engines (unlike older, simpler reference-counting garbage collectors, which could get stuck if two objects only referenced each other) — if neither object in the cycle is reachable from any root, mark-and-sweep correctly identifies and frees both, even though they still technically reference each other.
3
Real memory leaks in JavaScript almost always come from unintentionally keeping something reachable longer than intended: forgotten event listeners holding a reference to a detached DOM node, closures capturing large objects in scope longer than needed, timers (setInterval) that are never cleared and keep their callback's closure alive indefinitely, or entries accumulating in a global cache/array that's never pruned. None of these are garbage collector 'bugs' — they're cases where the code itself keeps something reachable (often unintentionally) that the developer actually intended to be discarded.
setInterval