Suggest an editImprove this articleRefine the answer for “Garbage collection in V8”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Garbage collection** automatically frees memory held by objects that no longer have any references: V8 marks reachable objects starting from root references, then sweeps the rest, splitting the heap into a young and an old generation for efficiency. **Key point:** the GC will not free an object while even one reference to it remains, which is exactly how memory leaks happen through forgotten references.Shown above the full answer for quick recall.Answer (EN)Image## 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: ```javascript let user = { name: 'Tim' }; user = null; // now nothing references the object → the GC will free its memory ``` ## 2. 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: 1. **New Space (the young generation)**, for recently created objects; 2. **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 ```javascript 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 memory ``` Once `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: ```javascript let cache = {}; function remember(key) { cache[key] = new Array(1e6).fill('*'); // holds a reference forever } ``` ## 10. A visual diagram of GC in V8 ```javascript ┌──────────────┐ │ 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 |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.