Fundamentals 10 min read

How V8’s Garbage Collector Works: From Scavenge to Mark‑Sweep

This article explains how the V8 JavaScript engine creates garbage data, the steps of its garbage‑collection algorithms, the roles of the minor (scavenger) and major (mark‑sweep) collectors, and modern optimizations like parallel, incremental, and concurrent collection to improve performance.

WeDoctor Frontend Technology
WeDoctor Frontend Technology
WeDoctor Frontend Technology
How V8’s Garbage Collector Works: From Scavenge to Mark‑Sweep

JavaScript is a garbage‑collected language whose memory is managed by the execution environment; V8 is a popular engine used in browsers and Node.js. This article examines how V8 performs efficient garbage collection.

How Garbage Data Is Created

Consider the following code:

let test = new Object();
test.a = new Array(10);

When this code runs, a global variable test is created and an empty object is allocated on the heap, with its address stored in test. Then an array of length 10 is created and assigned to test.a. The memory layout is shown below:

If we later assign a new object to test.a:

test.a = new Object()

The memory layout changes as shown:

Now the original array is unreachable from any root object and becomes garbage data.

Garbage Collection Algorithms

The garbage‑collection process consists of three steps:

Step 1: Reachability

Starting from GC Roots, the engine traverses all reachable objects:

Reachable objects are those found during traversal and must be kept in memory.

Unreachable objects are not found from any root, are marked, and become candidates for reclamation.

In a browser, GC Roots include the global window object, the DOM tree, and variables stored on the stack, among others.

Step 2: Reclaim Unreachable Objects

After marking, all objects identified as reclaimable are freed.

Step 3: Memory Compaction

Frequent reclamation can leave fragmented memory; compaction reorganizes memory to eliminate gaps, though some collectors (e.g., the minor collector) avoid fragmentation.

Minor and Major Garbage Collectors

V8 divides the heap into a young generation (1–8 MB, for short‑lived objects) and an old generation (larger, for long‑lived objects).

Minor (Scavenger) Collector

The minor collector handles the young generation, where most small objects reside.

Garbage in the young generation is processed with the Scavenge algorithm, using an object space and a free space as shown:

1. Mark and clean: objects in the object space are marked, then cleaned as illustrated:

The minor collector copies live objects to the free space, arranging them contiguously, which also performs memory compaction.

2. Role reversal: after copying, the former object space becomes the new free space and vice versa:

Major (Mark‑Sweep) Collector

The major collector handles the old generation, where large and long‑living objects reside.

Garbage in the old generation is reclaimed using a mark‑clear algorithm because copying large objects would be costly.

Garbage‑collection process:

1. Mark: starting from root objects, recursively traverse reachable objects; unreachable objects are considered garbage.

2. Sweep: the marked garbage is directly removed, as shown:

3. Compact: after sweeping, memory fragmentation may occur; a mark‑compact phase reorganizes memory to eliminate gaps, illustrated below:

Optimizing the Garbage Collector

Because JavaScript runs on the main thread, garbage collection can block script execution and cause UI jank.

V8 addresses this with parallel, incremental, and concurrent collection techniques:

1. Split a full collection into many small tasks to reduce pause times.

2. Offload marking and moving objects to background threads, minimizing main‑thread blocking.

The three techniques are often combined in practice.

Parallel Collection

Instead of a single thread handling collection, V8 spawns auxiliary threads to process the young generation in parallel, speeding up collection as shown:

The minor collector uses this parallel strategy, moving objects to free space concurrently while updating references.

Incremental Collection

Parallel collection still pauses the main thread for large objects; incremental collection breaks the marking phase into tiny chunks, reducing pause duration, as illustrated:

Concurrent Collection

Concurrent collection allows background threads to perform marking and sweeping while the main thread continues executing JavaScript, as shown:

In real applications, these three mechanisms are typically combined to achieve smooth performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performancev8Engine
WeDoctor Frontend Technology
Written by

WeDoctor Frontend Technology

Official WeDoctor Group frontend public account, sharing original tech articles, events, job postings, and occasional daily updates from our tech team.

0 followers
Reader feedback

How this landed with the community

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.