Fundamentals 30 min read

Understanding V8 Garbage Collection: Scavenger and Mark‑and‑Sweep Algorithms

V8’s garbage collector splits memory into young and old generations, using a fast Scavenger minor‑GC that marks live objects, evacuates them via semi‑space copying, and updates pointers with write barriers, while a concurrent mark‑and‑sweep major‑GC employs three‑color marking, black allocation, sweeping and optional parallel compaction, with adaptive triggering based on heap usage.

Tencent Technical Engineering
Tencent Technical Engineering
Tencent Technical Engineering
Understanding V8 Garbage Collection: Scavenger and Mark‑and‑Sweep Algorithms

1. Generational Layout

The generational hypothesis states that most objects die shortly after allocation. V8’s heap is divided into a young generation (further split into new space and old space ) and an old generation . Objects are allocated in new space, promoted to old space after surviving one or two minor collections.

JavaScript uses two kinds of garbage collection:

Minor GC – Scavenger algorithm, collects the young generation.

Major GC – Mark‑and‑Sweep algorithm, collects the old generation.

2. Scavenger Algorithm (Minor GC)

Scavenger works in three steps:

Marking : traverse from GC Roots to find live objects in the young generation.

Evacuating : copy live objects to to‑space (or directly to the old generation if they have already been promoted).

Pointer updating : update all references to the moved objects.

2.1 Marking

GC Roots include global objects (window, global), active objects in the current execution context, DOM nodes, references held by the event queue, and built‑in objects.

2.2 Cross‑generation Reference List

V8 maintains a write‑barrier‑generated list of old‑to‑new references, allowing the collector to skip scanning the entire old generation when marking young objects.

2.3 Write Barrier

During a write operation such as object.field = value , the write barrier records the new reference so that the Scavenger’s marking phase sees an up‑to‑date graph.

2.4 Semi‑Space

The young generation uses a semi‑space design: one half is from‑space (source) and the other half is to‑space (destination). After evacuation the roles are swapped.

2.5 Store Buffer and Remembered Set

Each page records reverse pointers in a store buffer . To avoid data races during parallel pointer updates, V8 replaces the store buffer with a remembered set that tracks which pages contain references to a given page.

2.6 Parallel Scavenger

Multiple threads start from different GC Roots, push unfinished sub‑tasks onto a global work list, and steal work when idle. This load‑balancing reduces total pause time by about 55%.

3. Mark‑and‑Sweep Algorithm (Major GC)

The classic algorithm consists of:

Marking : identify reachable (live) objects.

Sweeping : reclaim memory occupied by unreachable objects.

Compacting (optional) : relocate live objects to eliminate fragmentation.

3.1 Marking Phase

V8 uses a three‑color scheme (white, gray, black) and a concurrent worklist. Threads repeatedly take gray nodes, scan their fields, turn newly discovered white nodes gray, and finally color processed nodes black.

3.2 Write Barrier for Concurrent Marking

While the concurrent marking threads run, the main thread may modify object graphs. The write barrier records such mutations, turning newly referenced white objects gray so they are not missed.

3.3 Black Allocation

Objects that have survived two minor GCs are painted black early, allowing the next major GC to skip scanning them, which improves throughput by ~30%.

3.4 Sweeping Phase

Dead objects are turned into entries in a free‑list, which is later used for allocation.

3.5 Compaction Phase

Only heavily fragmented pages are compacted; the operation runs in parallel but still pauses the main thread.

4. Garbage‑Collection Trigger Timing

Minor GC is triggered when the young generation fills up, when a new allocation cannot be satisfied, or during idle periods (if enough idle time is available).

Major GC fires when the old generation exceeds a heuristic limit, when overall heap usage crosses a threshold, or when the browser detects a long‑idle page.

V8 also adapts the frequency dynamically, employs a low‑memory mode for devices with < 512 MB RAM, and runs a “Memory Reducer” to force a major GC on inactive pages.

5. References

Key V8 blog posts, source files (e.g., src/heap/scavenger.cc , src/heap/marking.cc ), and useful external articles are listed for further reading.

performanceJavaScriptMemory ManagementGarbage CollectionV8Mark and SweepScavenger
Tencent Technical Engineering
Written by

Tencent Technical Engineering

Official account of Tencent Technology. A platform for publishing and analyzing Tencent's technological innovations and cutting-edge developments.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.