Garbage collection in V8
1. What garbage collection is
Garbage collection is the process of automatically freeing memory held by objects that are no longer used by the program.
The idea:
If an object has no references, it can be safely removed from memory.
Example:
let user = { name: 'Tim' };
user = null; // now nothing references the object → the GC will free its memory2. How V8 manages memory
When you create an object, array, function or string, V8 allocates memory for it on the heap. V8 splits the heap into two parts:
- New Space (the young generation), for recently created objects;
- Old Space (the old generation), for long-lived objects.
3. Memory structure in V8
| Area | Purpose |
|---|---|
| Stack | Local variables and function calls (managed automatically) |
| Heap | Objects, arrays, functions and closures (managed by the GC) |
| New Space | New objects that live briefly |
| Old Space | Objects that survived several GC cycles |
| Code Space | Machine code compiled by the JIT compiler |
| Large Object Space | For very large objects (for example, long arrays) |
4. How the garbage collector works
V8 uses incremental, multi-threaded GC algorithms: The main stages are "Mark and Sweep".
1. Mark
V8 walks every object starting from the root set, variables reachable from the stack, the global scope, and so on. Every object reachable through references is marked as "live" (reachable).
2. Sweep
After the walk, whatever remains unmarked is treated as "garbage", and its memory is freed.
This guarantees only genuinely "dead" objects get removed.
5. The two-generation model (generational GC)
To improve efficiency, V8 splits the heap into generations:
The young generation
- Holds recently created objects.
- Collected often, but quickly (Minor GC).
- Algorithm: Scavenge (copying GC): live objects are copied from one half of memory to the other.
If an object "survives" several GC cycles, it's promoted to the old generation.
The old generation
- Holds long-lived objects (for example, closures, caches, large structures).
- Collected less often, but with more work (Major GC).
- Algorithm: Mark-Sweep / Mark-Compact, with optional parallel and incremental processing.
6. Modern V8 GC optimizations
V8 combines several GC strategies to minimize "stop-the-world" pause time:
| Technique | Purpose |
|---|---|
| Parallel GC | Part of the GC runs across several threads |
| Incremental GC | Splits collection into small steps so it doesn't block the Event Loop |
| Concurrent Marking | Marks objects in parallel with running JS |
| Compacting | Compacts memory to reduce heap fragmentation |
| Idle GC | The GC can run while the Event Loop is idle |
7. A visual example
function createUsers() {
let users = [];
for (let i = 0; i < 1_000_000; i++) {
users.push({ id: i });
}
return users;
}
createUsers(); // once it returns, users is no longer used → the GC will free its memoryOnce createUsers() returns, the users array and all of its objects become unreachable, and the GC clears their memory on the next cycle.
8. How GC affects performance
Pros:
- frees developers from manual memory management;
- prevents leaks and overflows.
Cons:
- can cause short pauses ("stop-the-world") that halt JS execution;
- if memory is heavily fragmented or there are too many objects, the GC can take noticeable time.
That's why it matters to write "GC-friendly" code:
- avoid unnecessary global variables;
- don't keep large structures cached without a reason;
- null out references to objects once they're no longer needed.
9. What the GC does not remove:
- objects that still have references;
- closures, if they hold onto their context;
- mutual references (A → B and B → A), as long as at least one is reachable from the root.
A leak example:
let cache = {};
function remember(key) {
cache[key] = new Array(1e6).fill('*'); // holds a reference forever
}10. A visual diagram of GC in V8
┌──────────────┐
│ Root Objects │ ← global variables, the call stack
└──────┬───────┘
▼
┌──────────────┐
│ Reachable │ ← marked objects
│ (live) │
└──────┬───────┘
▼
┌──────────────┐
│ Unreachable │ ← garbage → cleared
└──────────────┘11. Quick summary
| Point | Description |
|---|---|
| Garbage collection | Automatically frees memory from "dead" objects |
| Algorithm | Mark-and-Sweep + generational GC |
| Young generation | Collected often, quickly |
| Old generation | Collected rarely, but with more work |
| Optimizations | Incremental, Concurrent, Parallel, Compacting |
| Goal | A balance between speed and minimal pauses |
| The GC won't save you from a leak if a reference stays in your code | It never frees an object that still has a reference |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.