JavaScript Generational Garbage Collection Explained
Generational garbage collection is an automated memory management strategy used by modern JavaScript engines like V8 to optimize performance by categorizing allocated memory based on object lifespan. By dividing the heap into “Young” and “Old” spaces, the engine can frequently collect short-lived objects without scanning the entire memory footprint, drastically reducing execution pauses and CPU overhead.
The Foundation: The Weak Generational Hypothesis
The division of memory relies on an observed runtime truth called the Weak Generational Hypothesis, which states that the vast majority of objects die shortly after creation. In JavaScript, temporary variables, function arguments, and short-lived loop iterations are created, used, and discarded almost immediately. Generational garbage collection exploits this pattern by segregating brand-new allocations from persistent data.
The Young Generation (New Space)
The Young Generation, or New Space, is where all newly allocated JavaScript objects, arrays, and functions originate.
- Size and Structure: This space is deliberately kept small—typically between 1 MB and 64 MB depending on the device and engine configuration. It is internally divided into two contiguous memory segments: the Active Semi-space (Nursery/From-space) and the Inactive Semi-space (To-space).
- The Scavenger Algorithm: Memory in the Young Generation is collected via a fast, lightweight process called Scavenge (an implementation of Cheney’s copying algorithm).
- How It Works: When the active semi-space fills up, a Minor Garbage Collection (Minor GC) cycle triggers. The engine pauses execution briefly, scans for live (reachable) objects, and copies only the live objects directly into the inactive semi-space. The remaining dead objects in the active space are abandoned, and the roles of the two semi-spaces are instantly swapped.
Because only surviving objects are copied and most objects are already dead, Minor GC cycles execute in single-digit milliseconds.
Promotion: Moving from Young to Old Space
Objects do not stay in the Young Generation indefinitely. If an object survives consecutive Minor GC cycles (usually two rounds), the engine deems it a long-lived object and promotes it to the Old Generation. Direct allocation to the Old Generation can also occur if a newly created object is too large to fit into the Young Generation’s semi-spaces.
The Old Generation (Old Space)
The Old Generation, or Old Space, holds long-lived application state, global variables, closures, and persistent cache entries.
- Size and Structure: The Old Space is significantly larger than the New Space, often consuming hundreds of megabytes or gigabytes. It is typically divided into sub-areas, such as the Old Pointer Space (objects containing references to other objects) and the Old Data Space (raw data like strings, numbers, and byte arrays).
- The Mark-Sweep-Compact Algorithm: Because this
space is vast, moving objects via copying is too computationally
expensive. Instead, it relies on a Major GC cycle (also
called Mark-Sweep-Compact):
- Marking: The engine traverses the entire object graph starting from the roots (e.g., the global object, active call stack) to identify all reachable objects.
- Sweeping: The engine scans the memory addresses of dead objects and adds them to a “free list” for future allocations.
- Compacting: To prevent memory fragmentation, the engine selectively shifts fragmented, live objects into contiguous memory blocks.
Performance Benefits of Space Division
By separating memory into distinct generations, the JavaScript engine avoids running costly full-heap traversals on every allocation spike. The fast, frequent Scavenge operations clear out transient objects in the Young Space with minimal interruption, while the resource-intensive Mark-Sweep-Compact algorithm in the Old Space runs only when necessary, often utilizing incremental and concurrent background threads to keep web applications responsive.