Suggest an editImprove this articleRefine the answer for “The garbage collector (GC) in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The garbage collector is a mechanism of the JS engine (V8, for example) that automatically frees the memory held by objects that have become unreachable.** The decision is not based on whether the object is "needed" but on reachability: the engine starts from the roots (`globalThis`, the call stack, closures) and marks everything it can walk to through references; everything unmarked is removed. The classic algorithm is mark-and-sweep, and in V8 it is split into Minor GC (Scavenge, for young objects) and Major GC (Mark-Sweep-Compact, for old ones). This is exactly why circular references are not a problem: if the cycle cannot be reached from a root, both objects are collected. ```javascript let user = { name: 'Alice' }; let admin = user; // two references to one object user = null; // still reachable through admin admin = null; // now unreachable, GC will free it ``` **Key point:** GC removes what is unreachable, not what is unneeded; as long as a live reference from a root exists, the object stays in memory.Shown above the full answer for quick recall.Answer (EN)Image**The garbage collector (GC) is a mechanism of the JavaScript engine (V8, for example) that automatically frees the memory occupied by objects that have become unreachable.** In other words, GC removes from memory everything that nothing points at any more, so that resources are not wasted and memory does not overflow. ## Theory ### TL;DR - GC frees memory automatically; there is no manual `free()` in JavaScript. - There is exactly one criterion: reachability, not the "logical need" for an object. - The roots of reachability: the global object, the call stack, live closures. - The base algorithm is mark-and-sweep, sometimes with a compact phase that defragments memory. - V8 has two modes: Minor GC (Scavenge) for young objects and Major GC (Mark-Sweep-Compact) for old ones. - Circular references do not bother GC: all that matters is whether the object can be reached from a root. - A leak is not a broken GC, it is a live reference to something you no longer need. ### Quick example The engine manages memory like this: 1. It allocates memory for a new object: ```javascript let user = { name: 'Tim' }; // memory allocated ``` 2. The variable stops pointing at the object: ```javascript user = null; // the old reference is gone ``` 3. GC sees that the object `{ name: 'Tim' }` is unreachable and frees the memory on its next cycle. ### The key concept: reachability > In JS memory is not cleared by hand, it is cleared by the principle of reachability. Reachable objects: - global variables (`window`, `global`, `globalThis`); - local variables on the stack, while the function is running; - objects referenced by other reachable objects. Unreachable objects: - objects with no references from any reachable place. ```javascript let user = { name: 'Alice' }; let admin = user; // two references to one object user = null; // still reachable through admin admin = null; // now unreachable, GC will remove it ``` ### An example with a reference chain and a cycle ```javascript function createUser() { const user = { name: 'Bob' }; const address = { city: 'Paris' }; user.addr = address; address.owner = user; // circular reference return user; } let person = createUser(); ``` Here `user` points at `address` and `address` points back at `user`. If you then write: ```javascript person = null; ``` both objects become unreachable, because there is no longer a path to them from a root, and GC frees both of them despite the cycle. The JS collector handles such cycles: it does not count references, it checks reachability from the roots. ### The algorithm, using V8 as the example V8 (the engine of Chrome and Node.js) uses the **mark-and-sweep** algorithm: 1. **Mark.** GC walks from the root objects (`window`, `global`, the call stack) and marks everything reachable. 2. **Sweep.** Everything that was not marked is removed from memory. 3. **Compact.** Sometimes memory is compacted to remove fragmentation and free contiguous blocks. On top of that, V8 has two kinds of cycle: - **Minor GC (Scavenge)** for "young" objects: new ones, which usually die quickly. It runs often and fast. - **Major GC (Mark-Sweep-Compact)** for "old" objects: the ones that survived several Minor GCs. It runs less often and takes longer. ### How GC affects performance - GC runs automatically and mostly asynchronously, but it sometimes causes small pauses (GC pauses). - The more "live" objects there are, the longer a collection cycle takes. - Memory leaks get in the way of GC: it treats dangling references as live and cannot free anything. > Optimal code means fewer long-lived objects plus dropping references at the right time. ### What GC does not do | Does not do | Why | | --- | --- | | Does not clear everything at once | So that it does not block the running program | | Does not see "logical uselessness" | It only looks at the absence of references, it is not intelligence | | Cannot be driven manually | There is no `free()` as in C++; the `delete` operator in JS removes a property, not memory | | Does not clean up global objects | They are always reachable through `window` or `globalThis` | ### How to inspect GC and memory **In the browser:** - Chrome DevTools, the **Memory** tab, "Heap snapshot"; - the **Performance** tab, the **Memory** section, the "Record" button; - the console: `performance.memory.usedJSHeapSize`. **In Node.js:** - the `--inspect` flag, the `heapdump` and `clinic.js` packages, the `process.memoryUsage()` method. Summary table: | What | Description | | --- | --- | | **GC (Garbage Collector)** | The mechanism that frees memory automatically | | **Principle** | Removes objects that cannot be reached from a root | | **Main algorithm** | Mark-and-sweep | | **The leak problem** | The object is still reachable but is no longer needed | | **The fix** | Drop references, clear timers and listeners | | **Pros** | Simplicity, memory safety | | **Cons** | Possible pauses and hidden leaks | ### Common mistakes | Mistake | What happens | | --- | --- | | Global variables | They stay reachable forever, GC will never collect them | | Timers and listeners without cleanup | The references keep closures alive together with everything inside them | | DOM references after the element is removed | The node is out of the document but a `ref` holds it, so GC is powerless | | Closures over large objects | Leaks through scope: one tiny function keeps megabytes alive | Two more things are worth remembering. First, "the object is no longer needed" and "the object is unreachable" are different statements, and GC understands only the second one. Second, there is no way to force a reliable GC run from application code, so every optimisation comes down to releasing references in time rather than asking the collector to do some work.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.