Docs

24.3-Garbage-Collection-Advanced

22.3 Advanced Garbage Collection

Understanding V8's garbage collection helps you write memory-efficient code and avoid performance issues. This section covers the internals of V8's generational and incremental GC.


Table of Contents


Garbage Collection Fundamentals

JavaScript automatically manages memory. The garbage collector finds and frees unused objects.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MEMORY LIFECYCLE                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. ALLOCATION                                                      β”‚
β”‚     const obj = { x: 1, y: 2 };                                    β”‚
β”‚     const arr = [1, 2, 3, 4, 5];                                   β”‚
β”‚                                                                     β”‚
β”‚  2. USE                                                             β”‚
β”‚     console.log(obj.x);                                             β”‚
β”‚     arr.forEach(n => process(n));                                   β”‚
β”‚                                                                     β”‚
β”‚  3. COLLECTION (Automatic)                                          β”‚
β”‚     // When obj and arr are no longer reachable                     β”‚
β”‚     // GC reclaims the memory                                       β”‚
β”‚                                                                     β”‚
β”‚  The Challenge:                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  β€’ Must find ALL unreachable objects                        β”‚    β”‚
β”‚  β”‚  β€’ Must not free objects still in use                       β”‚    β”‚
β”‚  β”‚  β€’ Should minimize pause times                              β”‚    β”‚
β”‚  β”‚  β€’ Should be memory efficient                               β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Reachability

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    REACHABILITY CONCEPT                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  ROOT OBJECTS (Always Reachable):                                   β”‚
β”‚  β€’ Global object (window/global)                                    β”‚
β”‚  β€’ Currently executing functions (call stack)                       β”‚
β”‚  β€’ Active closures                                                  β”‚
β”‚                                                                     β”‚
β”‚  Reachability Chain:                                                β”‚
β”‚                                                                     β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”                                                       β”‚
β”‚    β”‚ Roots  β”‚                                                       β”‚
β”‚    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜                                                       β”‚
β”‚         β”‚                                                           β”‚
β”‚    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚    β”‚ Obj A  │────→│ Obj B  │────→│ Obj C  β”‚  ← REACHABLE           β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
β”‚                                                                     β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”                                       β”‚
β”‚    β”‚ Obj X  │────→│ Obj Y  β”‚  ← UNREACHABLE (no path from roots)   β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                       β”‚
β”‚                                                                     β”‚
β”‚  Example:                                                           β”‚
β”‚  let user = { name: "Alice" };  // Reachable via 'user'            β”‚
β”‚  user = null;                    // Now unreachable - GC can free  β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

V8 Memory Structure

V8 divides the heap into different spaces for efficient memory management.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    V8 HEAP STRUCTURE                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                          HEAP                                β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚   β”‚
β”‚  β”‚  β”‚              NEW SPACE (Young Generation)               β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β”‚    From-Space    β”‚  β”‚     To-Space     β”‚            β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β”‚    (Active)      β”‚  β”‚    (Empty)       β”‚            β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β”‚   1-8 MB each    β”‚  β”‚                  β”‚            β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚   β”‚
β”‚  β”‚                                                             β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚   β”‚
β”‚  β”‚  β”‚              OLD SPACE (Old Generation)                 β”‚β”‚   β”‚
β”‚  β”‚  β”‚                                                         β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β€’ Objects that survived young generation               β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β€’ Large objects (allocated directly here)              β”‚β”‚   β”‚
β”‚  β”‚  β”‚  β€’ Size: Grows dynamically (up to heap limit)          β”‚β”‚   β”‚
β”‚  β”‚  β”‚                                                         β”‚β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚   β”‚
β”‚  β”‚                                                             β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚   β”‚
β”‚  β”‚  β”‚    Code Space     β”‚  β”‚   Map Space       β”‚              β”‚   β”‚
β”‚  β”‚  β”‚  (Compiled code)  β”‚  β”‚ (Hidden classes)  β”‚              β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚   β”‚
β”‚  β”‚                                                             β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                     β”‚   β”‚
β”‚  β”‚  β”‚ Large Object Spaceβ”‚                                     β”‚   β”‚
β”‚  β”‚  β”‚  (Objects > 1MB)  β”‚                                     β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                     β”‚   β”‚
β”‚  β”‚                                                             β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Memory Spaces Explained

SpacePurposeGC TypeSize
New SpaceNew objectsMinor GC (Scavenger)1-8 MB per semi-space
Old SpaceLong-lived objectsMajor GC (Mark-Sweep)Dynamic
Code SpaceJIT compiled codeRarely collectedDynamic
Map SpaceHidden classesCollected with old spaceDynamic
Large Object SpaceObjects > 1MBMajor GCDynamic

Generational Garbage Collection

V8 uses the "generational hypothesis": most objects die young.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GENERATIONAL HYPOTHESIS                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  Object Lifetime Distribution:                                      β”‚
β”‚                                                                     β”‚
β”‚  Objects β”‚                                                          β”‚
β”‚  Created β”‚β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                                     β”‚
β”‚          β”‚β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                                            β”‚
β”‚          β”‚β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                                                  β”‚
β”‚          β”‚β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                                                     β”‚
β”‚          β”‚β–ˆβ–ˆβ–ˆ                                                       β”‚
β”‚          β”‚β–ˆβ–ˆ                                                        β”‚
β”‚          β”‚β–ˆ                                                         β”‚
β”‚          β”‚β–ˆ                                                         β”‚
β”‚          β”‚β–ˆ                                                         β”‚
β”‚          └──────────────────────────────────────────────────────    β”‚
β”‚            Short    Medium    Long          Object Lifespan         β”‚
β”‚                                                                     β”‚
β”‚  Key Insight:                                                       β”‚
β”‚  β€’ Most objects (80-90%) die very young                            β”‚
β”‚  β€’ Few objects live for a long time                                β”‚
β”‚  β€’ Optimize for the common case (short-lived objects)              β”‚
β”‚                                                                     β”‚
β”‚  Strategy:                                                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  YOUNG GENERATION          OLD GENERATION                  β”‚    β”‚
β”‚  β”‚  β€’ Small, fast GC          β€’ Large, slower GC              β”‚    β”‚
β”‚  β”‚  β€’ Runs frequently         β€’ Runs less often               β”‚    β”‚
β”‚  β”‚  β€’ Scavenge algorithm      β€’ Mark-Sweep-Compact            β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Scavenger (Minor GC)

The Scavenger handles the young generation using a copying algorithm.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SCAVENGE ALGORITHM                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  BEFORE SCAVENGE:                                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚      From-Space        β”‚  β”‚       To-Space         β”‚            β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”  β”‚  β”‚       (Empty)          β”‚            β”‚
β”‚  β”‚ β”‚ A β”‚β”‚ B β”‚β”‚ C β”‚β”‚ D β”‚  β”‚  β”‚                        β”‚            β”‚
β”‚  β”‚ β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜  β”‚  β”‚                        β”‚            β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”            β”‚  β”‚                        β”‚            β”‚
β”‚  β”‚ β”‚ E β”‚β”‚ F β”‚            β”‚  β”‚                        β”‚            β”‚
β”‚  β”‚ β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜            β”‚  β”‚                        β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                     β”‚
β”‚  Assume: A, C, E are reachable; B, D, F are garbage               β”‚
β”‚                                                                     β”‚
β”‚  AFTER SCAVENGE:                                                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚      From-Space        β”‚  β”‚       To-Space         β”‚            β”‚
β”‚  β”‚       (Empty)          β”‚  β”‚ β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”β”Œβ”€β”€β”€β”       β”‚            β”‚
β”‚  β”‚                        β”‚  β”‚ β”‚ A β”‚β”‚ C β”‚β”‚ E β”‚       β”‚            β”‚
β”‚  β”‚                        β”‚  β”‚ β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜β””β”€β”€β”€β”˜       β”‚            β”‚
β”‚  β”‚                        β”‚  β”‚                        β”‚            β”‚
β”‚  β”‚                        β”‚  β”‚  Survivors copied      β”‚            β”‚
β”‚  β”‚                        β”‚  β”‚  Compacted together    β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                     β”‚
β”‚  Then: Spaces are SWAPPED                                           β”‚
β”‚  β€’ To-Space becomes new From-Space                                  β”‚
β”‚  β€’ Old From-Space becomes new To-Space                             β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Object Promotion

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    OBJECT PROMOTION                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  Objects are PROMOTED to Old Space when:                           β”‚
β”‚                                                                     β”‚
β”‚  1. They survive TWO scavenges                                     β”‚
β”‚  2. To-Space is more than 25% full                                 β”‚
β”‚                                                                     β”‚
β”‚  First Scavenge:                                                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚  β”‚ From-Space  β”‚         β”‚  To-Space   β”‚                           β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”      β”‚  ──→   β”‚  β”Œβ”€β”€β”€β”      β”‚                           β”‚
β”‚  β”‚  β”‚ A β”‚      β”‚ copy    β”‚  β”‚ A β”‚      β”‚  A survives (age = 1)    β”‚
β”‚  β”‚  β””β”€β”€β”€β”˜      β”‚         β”‚  β””β”€β”€β”€β”˜      β”‚                           β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
β”‚                                                                     β”‚
β”‚  Second Scavenge:                                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚ From-Space  β”‚         β”‚  To-Space   β”‚  β”‚  Old Space  β”‚         β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”      β”‚         β”‚             β”‚  β”‚  β”Œβ”€β”€β”€β”      β”‚         β”‚
β”‚  β”‚  β”‚ A β”‚      β”‚  ──────────────────────→ β”‚  β”‚ A β”‚      β”‚  PROMOTEDβ”‚
β”‚  β”‚  β””β”€β”€β”€β”˜      β”‚                          β”‚  β””β”€β”€β”€β”˜      β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                     β”‚
β”‚  Promotion Benefits:                                                β”‚
β”‚  β€’ Long-lived objects don't get copied repeatedly                  β”‚
β”‚  β€’ Young GC stays fast (fewer objects to scan)                     β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Scavenger Characteristics

AspectDetails
AlgorithmCheney's copying algorithm
SpeedVery fast (1-2ms typical)
FrequencyOften (when new space fills)
Stop-the-worldYes, but very short pause
Memory overhead2x (two semi-spaces)
FragmentationNone (compacting by nature)

Mark-Sweep-Compact (Major GC)

Major GC handles the old generation using mark-sweep-compact algorithm.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MARK-SWEEP-COMPACT                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  PHASE 1: MARK                                                      β”‚
β”‚  ───────────────                                                   β”‚
β”‚  Start from roots, mark all reachable objects                       β”‚
β”‚                                                                     β”‚
β”‚    Roots                                                            β”‚
β”‚      β”‚                                                              β”‚
β”‚      β–Ό                                                              β”‚
β”‚    β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”                                       β”‚
β”‚    β”‚ A │────→│ B │────→│ C β”‚   ← Marked (reachable)                β”‚
β”‚    β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜                                       β”‚
β”‚       ●         ●         ●                                         β”‚
β”‚                                                                     β”‚
β”‚    β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”                                                 β”‚
β”‚    β”‚ X β”‚     β”‚ Y β”‚   ← Not marked (garbage)                        β”‚
β”‚    β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜                                                 β”‚
β”‚                                                                     β”‚
β”‚  PHASE 2: SWEEP                                                     β”‚
β”‚  ────────────────                                                  β”‚
β”‚  Free memory of unmarked objects                                    β”‚
β”‚                                                                     β”‚
β”‚    β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”                  β”‚
β”‚    β”‚ A β”‚     β”‚ B β”‚     β”‚   β”‚     β”‚ C β”‚     β”‚   β”‚                  β”‚
β”‚    β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜                  β”‚
β”‚       ●         ●        FREE       ●        FREE                   β”‚
β”‚                                                                     β”‚
β”‚  PHASE 3: COMPACT (Optional)                                        β”‚
β”‚  ──────────────────────────                                        β”‚
β”‚  Move objects to eliminate fragmentation                            β”‚
β”‚                                                                     β”‚
β”‚    BEFORE:  β”‚ A β”‚   β”‚ B β”‚       β”‚ C β”‚       β”‚                      β”‚
β”‚    AFTER:   β”‚ A β”‚ B β”‚ C β”‚                   β”‚ FREE                 β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tri-Color Marking

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    TRI-COLOR MARKING                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  Three Colors:                                                      β”‚
β”‚  β€’ WHITE: Not yet visited (potentially garbage)                    β”‚
β”‚  β€’ GRAY:  Visited, but children not scanned                        β”‚
β”‚  β€’ BLACK: Visited and all children scanned                         β”‚
β”‚                                                                     β”‚
β”‚  Algorithm:                                                         β”‚
β”‚                                                                     β”‚
β”‚  1. Initially all objects are WHITE                                 β”‚
β”‚  2. Roots are marked GRAY                                          β”‚
β”‚  3. While GRAY objects exist:                                       β”‚
β”‚     a. Pick a GRAY object                                          β”‚
β”‚     b. Mark its WHITE children GRAY                                β”‚
β”‚     c. Mark the object BLACK                                       β”‚
β”‚  4. All WHITE objects are garbage                                  β”‚
β”‚                                                                     β”‚
β”‚  Visual:                                                            β”‚
β”‚                                                                     β”‚
β”‚  Step 1:     ○──○──○──○      (all white)                          β”‚
β”‚              β”‚                                                      β”‚
β”‚            Root                                                     β”‚
β”‚                                                                     β”‚
β”‚  Step 2:     ◐──○──○──○      (root is gray)                       β”‚
β”‚                                                                     β”‚
β”‚  Step 3:     ●──◐──○──○      (root black, child gray)             β”‚
β”‚                                                                     β”‚
β”‚  Step 4:     ●──●──◐──○      (continue marking)                   β”‚
β”‚                                                                     β”‚
β”‚  Step 5:     ●──●──●──○      (one object remains white = garbage) β”‚
β”‚                                                                     β”‚
β”‚  Legend: β—‹ = WHITE, ◐ = GRAY, ● = BLACK                           β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Incremental and Concurrent GC

V8 uses various techniques to reduce pause times.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    PAUSE TIME STRATEGIES                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  STOP-THE-WORLD (Blocking)                                          β”‚
β”‚  ─────────────────────────                                         β”‚
β”‚     JavaScript β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ         β”‚
β”‚     GC                         β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                         β”‚
β”‚                                │← Pause β†’β”‚                          β”‚
β”‚                                                                     β”‚
β”‚  Problem: Long pauses (100ms+) cause jank                          β”‚
β”‚                                                                     β”‚
β”‚  INCREMENTAL MARKING                                                β”‚
β”‚  ──────────────────                                                β”‚
β”‚     JavaScript β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ          β”‚
β”‚     GC             β–‘    β–‘    β–‘    β–‘    β–‘    β–‘                       β”‚
β”‚                    β”‚    Small increments   β”‚                        β”‚
β”‚                                                                     β”‚
β”‚  Mark in small chunks interleaved with JavaScript                   β”‚
β”‚                                                                     β”‚
β”‚  CONCURRENT MARKING                                                 β”‚
β”‚  ─────────────────                                                 β”‚
β”‚     JavaScript β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ          β”‚
β”‚     GC (thread) β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘                      β”‚
β”‚                 │←── Marking in parallel ──→│                       β”‚
β”‚                                                                     β”‚
β”‚  Mark on a separate thread while JavaScript runs                   β”‚
β”‚                                                                     β”‚
β”‚  PARALLEL SCAVENGING                                                β”‚
β”‚  ──────────────────                                                β”‚
β”‚     JavaScript β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ          β”‚
β”‚     GC Thread 1                β–‘β–‘β–‘                                  β”‚
β”‚     GC Thread 2                β–‘β–‘β–‘                                  β”‚
β”‚     GC Thread 3                β–‘β–‘β–‘                                  β”‚
β”‚                                │← Short pause, parallel work β”‚      β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

V8's Orinoco GC

V8's modern garbage collector (Orinoco) combines multiple techniques:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ORINOCO GC FEATURES                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. PARALLEL SCAVENGING                                             β”‚
β”‚     β€’ Multiple threads evacuate young generation                    β”‚
β”‚     β€’ Reduces minor GC pause time                                   β”‚
β”‚                                                                     β”‚
β”‚  2. CONCURRENT MARKING                                              β”‚
β”‚     β€’ Marking happens on background threads                         β”‚
β”‚     β€’ Main thread continues executing JavaScript                    β”‚
β”‚     β€’ Only short atomic pause for finalization                     β”‚
β”‚                                                                     β”‚
β”‚  3. INCREMENTAL MARKING                                             β”‚
β”‚     β€’ Mark objects in small steps                                   β”‚
β”‚     β€’ Interleaved with JavaScript execution                        β”‚
β”‚     β€’ Write barriers track mutations                                β”‚
β”‚                                                                     β”‚
β”‚  4. LAZY SWEEPING                                                   β”‚
β”‚     β€’ Sweep pages lazily as memory is needed                       β”‚
β”‚     β€’ Spread sweeping work over time                               β”‚
β”‚                                                                     β”‚
β”‚  5. CONCURRENT COMPACTION                                           β”‚
β”‚     β€’ Move objects on background thread                            β”‚
β”‚     β€’ Update pointers incrementally                                β”‚
β”‚                                                                     β”‚
β”‚  Timeline Example:                                                  β”‚
β”‚                                                                     β”‚
β”‚     Main Thread  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ       β”‚
β”‚     Worker 1     β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘       β”‚
β”‚     Worker 2     β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘       β”‚
β”‚                          └── Concurrent marking β”€β”€β”˜                 β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Memory Leaks and Detection

Common patterns that cause memory leaks in JavaScript.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    COMMON MEMORY LEAKS                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. FORGOTTEN EVENT LISTENERS                                       β”‚
β”‚                                                                     β”‚
β”‚     element.addEventListener('click', handler);                     β”‚
β”‚     // Later: element removed, but handler still referenced        β”‚
β”‚     // Fix: element.removeEventListener('click', handler);         β”‚
β”‚                                                                     β”‚
β”‚  2. DETACHED DOM NODES                                              β”‚
β”‚                                                                     β”‚
β”‚     const nodes = [];                                               β”‚
β”‚     function onClick() {                                            β”‚
β”‚       const div = document.createElement('div');                   β”‚
β”‚       nodes.push(div);  // div is retained even if removed         β”‚
β”‚     }                                                               β”‚
β”‚                                                                     β”‚
β”‚  3. CLOSURES OVER LARGE SCOPES                                      β”‚
β”‚                                                                     β”‚
β”‚     function process() {                                            β”‚
β”‚       const hugeData = loadHugeData();                             β”‚
β”‚       return function() {                                           β”‚
β”‚         // Closure keeps hugeData alive!                           β”‚
β”‚         return doSomething();                                       β”‚
β”‚       };                                                            β”‚
β”‚     }                                                               β”‚
β”‚                                                                     β”‚
β”‚  4. GROWING CACHES                                                  β”‚
β”‚                                                                     β”‚
β”‚     const cache = {};                                               β”‚
β”‚     function getData(key) {                                         β”‚
β”‚       if (!cache[key]) {                                           β”‚
β”‚         cache[key] = fetchData(key);  // Never cleaned up!        β”‚
β”‚       }                                                             β”‚
β”‚       return cache[key];                                            β”‚
β”‚     }                                                               β”‚
β”‚                                                                     β”‚
β”‚  5. CIRCULAR REFERENCES (Historical - modern GCs handle this)      β”‚
β”‚                                                                     β”‚
β”‚     const a = {};                                                   β”‚
β”‚     const b = {};                                                   β”‚
β”‚     a.ref = b;                                                      β”‚
β”‚     b.ref = a;  // Not a leak in modern V8                         β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Detecting Memory Leaks

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    LEAK DETECTION STRATEGIES                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. CHROME DEVTOOLS HEAP SNAPSHOTS                                 β”‚
β”‚                                                                     β”‚
β”‚     Take multiple snapshots β†’ Compare β†’ Find growing objects       β”‚
β”‚                                                                     β”‚
β”‚     Snapshot 1: 10 MB                                               β”‚
β”‚     Snapshot 2: 15 MB  (+5 MB - investigate!)                      β”‚
β”‚     Snapshot 3: 20 MB  (+5 MB - likely leak!)                      β”‚
β”‚                                                                     β”‚
β”‚  2. ALLOCATION TIMELINE                                             β”‚
β”‚                                                                     β”‚
β”‚     Record allocations over time                                    β”‚
β”‚     Blue bars = allocated, Gray = freed                            β”‚
β”‚     Growing blue = leak                                             β”‚
β”‚                                                                     β”‚
β”‚     β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘                            β”‚
β”‚         Normal: allocate, then freed                                β”‚
β”‚                                                                     β”‚
β”‚     β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ              β”‚
β”‚         Leak: allocations not freed                                 β”‚
β”‚                                                                     β”‚
β”‚  3. NODE.JS FLAGS                                                   β”‚
β”‚                                                                     β”‚
β”‚     node --expose-gc --trace-gc script.js                          β”‚
β”‚     process.memoryUsage()                                           β”‚
β”‚                                                                     β”‚
β”‚  4. PERFORMANCE.MEMORY (Chrome)                                     β”‚
β”‚                                                                     β”‚
β”‚     console.log(performance.memory.usedJSHeapSize);                β”‚
β”‚     // Monitor over time                                            β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Optimization Strategies

Strategy 1: Object Pooling

// Instead of creating many short-lived objects:
// BAD
function process(data) {
  return { x: data.x * 2, y: data.y * 2 }; // New object each time
}

// GOOD: Reuse objects from a pool
class VectorPool {
  constructor(size = 100) {
    this.pool = Array.from({ length: size }, () => ({ x: 0, y: 0 }));
    this.index = 0;
  }

  acquire(x, y) {
    const obj = this.pool[this.index];
    this.index = (this.index + 1) % this.pool.length;
    obj.x = x;
    obj.y = y;
    return obj;
  }
}

Strategy 2: Avoid Closures Over Large Data

// BAD: Closure retains large data
function createProcessor(hugeData) {
  return function process(index) {
    return hugeData[index]; // hugeData never freed
  };
}

// GOOD: Only capture what's needed
function createProcessor(hugeData) {
  const lookup = new Map(); // Extract needed data
  hugeData.forEach((item, i) => lookup.set(i, item.value));
  return function process(index) {
    return lookup.get(index);
  };
}

Strategy 3: Bounded Caches

// BAD: Unbounded cache
const cache = {};

// GOOD: Use LRU cache with limit
class LRUCache {
  constructor(maxSize = 100) {
    this.maxSize = maxSize;
    this.cache = new Map();
  }

  get(key) {
    if (this.cache.has(key)) {
      const value = this.cache.get(key);
      this.cache.delete(key);
      this.cache.set(key, value); // Move to end
      return value;
    }
    return undefined;
  }

  set(key, value) {
    if (this.cache.has(key)) {
      this.cache.delete(key);
    } else if (this.cache.size >= this.maxSize) {
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey); // Remove oldest
    }
    this.cache.set(key, value);
  }
}

Strategy 4: WeakMap for Object Metadata

// BAD: Strong reference prevents GC
const metadata = new Map();
function setMeta(obj, data) {
  metadata.set(obj, data); // obj can't be GC'd!
}

// GOOD: WeakMap allows GC
const metadata = new WeakMap();
function setMeta(obj, data) {
  metadata.set(obj, data); // obj can be GC'd
}

Key Takeaways

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GC SUMMARY                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  GENERATIONAL GC:                                                   β”‚
β”‚  β€’ Young generation: Small, fast, frequent GC (Scavenger)          β”‚
β”‚  β€’ Old generation: Large, slower, less frequent GC (Mark-Sweep)    β”‚
β”‚  β€’ Objects promoted after surviving 2 scavenges                    β”‚
β”‚                                                                     β”‚
β”‚  MODERN V8 (ORINOCO):                                              β”‚
β”‚  β€’ Parallel: Multiple GC threads                                    β”‚
β”‚  β€’ Concurrent: GC runs alongside JavaScript                        β”‚
β”‚  β€’ Incremental: Work spread over time                              β”‚
β”‚  β€’ Result: Minimal pause times                                      β”‚
β”‚                                                                     β”‚
β”‚  AVOID MEMORY LEAKS:                                                β”‚
β”‚  βœ… Remove event listeners when done                               β”‚
β”‚  βœ… Clear references to detached DOM nodes                         β”‚
β”‚  βœ… Avoid closures over large data                                 β”‚
β”‚  βœ… Use bounded caches (LRU)                                       β”‚
β”‚  βœ… Use WeakMap/WeakSet for object metadata                        β”‚
β”‚                                                                     β”‚
β”‚  OPTIMIZE ALLOCATIONS:                                              β”‚
β”‚  βœ… Reuse objects (object pooling)                                 β”‚
β”‚  βœ… Avoid creating objects in hot loops                            β”‚
β”‚  βœ… Pre-allocate arrays when size is known                         β”‚
β”‚  βœ… Prefer primitives over objects when possible                   β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Next Steps

Continue to 22.4 ES Modules Internals to understand how JavaScript modules are loaded, parsed, and executed.

.3 Garbage Collection Advanced - JavaScript Tutorial | DeepML