V8 JavaScript Engine
V8 is Google's open-source JavaScript engine written in C++. It compiles JavaScript to native machine code using JIT compilation and manages memory via garbage collection. Node.js embeds V8 to execute JavaScript on the server.
V8 is like a two-gear car: Ignition is first gear (slow but always works), TurboFan is sixth gear (blazing fast but stalls if road conditions change—deoptimization). Garbage collection is the mandatory pit stop that freezes the entire race.
V8 uses a multi-tier JIT pipeline: Ignition (bytecode interpreter) executes code initially, collecting type feedback. TurboFan (optimizing compiler) recompiles hot functions to optimized machine code using that feedback. If a function's types change (deoptimization), V8 falls back to Ignition. V8 manages the heap with generational garbage collection: a young generation (Scavenger/minor GC) for short-lived objects, and old generation (Mark-Sweep-Compact/major GC) for long-lived ones.
V8's heap is split into: new space (small, collected frequently via Cheney's semi-space algorithm), old space (large, collected via incremental marking + lazy sweeping), code space (compiled code), large object space, and map space (hidden class descriptors). 'Hidden classes' (internal shapes/maps) are V8's key optimization: objects with the same property assignment order share a hidden class, enabling inline cache (IC) hits. Adding properties in a different order or adding properties post-construction creates new hidden classes, causing IC misses and deoptimization. Node.js exposes V8 flags via --v8-options; --max-old-space-size controls old generation heap size (default ~1.5GB on 64-bit).
V8 JIT-compiles JavaScript using Ignition for initial interpretation and TurboFan for optimized machine code on hot paths. It uses generational garbage collection—frequent minor GC for short-lived objects and incremental major GC for long-lived ones. For production Node.js, understanding --max-old-space-size, avoiding heap fragmentation, and not breaking hidden class assumptions (consistent object shapes) are key performance levers.
Many engineers think GC pauses are irrelevant in Node.js because it's 'async'. Major GC (mark-sweep) stops all JavaScript execution on the main thread. A 500ms GC pause will stall every in-flight request for that duration. Monitoring process.memoryUsage().heapUsed and GC pause metrics is non-negotiable in production.