Expert · Performance and Node.js · topic 53 of 61 · 25 min
Memory and garbage collection
Explanation
Stack and heap in plain words
While a function runs, its small local values live in a fast, short-lived area called the stack; they vanish when the function returns. Objects, arrays, closures and strings live in a larger area called the heap, where they stay as long as something refers to them.
Garbage collection and reachability
You never free memory yourself in JavaScript. The engine's garbage collector (GC) regularly finds values that are no longer reachable, meaning no chain of references leads to them from the "roots" (global variables, the current call stack, active closures), and reuses their memory.
let user = { name: 'Asha', photo: new Array(1e6).fill(0) };
user = null; // the big object is now unreachable → the GC can free it
const cache = [];
function remember(item) { cache.push(item); } // everything pushed stays reachable foreverCommon leaks
| Leak | Why it leaks | Fix |
|---|---|---|
| Ever-growing cache or array | A global Map/array keeps every entry | Limit size (LRU), add expiry, or use WeakMap for object keys |
| Forgotten setInterval | The timer and its closure live until cleared | clearInterval when done (e.g. when a page or component closes) |
| Event listeners never removed | The element/handler and its closure stay alive | removeEventListener, or AbortController signal |
| Closures holding big data | An inner function keeps the whole outer variable | Keep only the small part you need |
| Detached DOM nodes | Removed elements still referenced from JS | Drop the references after removing |
// Leaky: a "recent searches" cache that grows forever on a server
const recent = new Map();
function track(userId, query) {
recent.set(`${userId}:${Date.now()}`, query); // never deleted
}
// Fixed: keep only the newest 100 entries
const MAX = 100;
function trackSafe(userId, query) {
recent.set(`${userId}:${Date.now()}`, query);
if (recent.size > MAX) recent.delete(recent.keys().next().value); // oldest first
}WeakMap and WeakRef
A WeakMap keeps a value attached to an object key without keeping that key alive. When the object is no longer used elsewhere, its entry disappears automatically: perfect for "extra data about a DOM element or request object". WeakRef and FinalizationRegistry exist for advanced cases, but their timing is unpredictable, so avoid them unless you really need them.
Finding leaks
- Watch memory over time: in Node, process.memoryUsage().heapUsed; in the browser, the Memory panel of DevTools.
- Repeat an action many times (open and close a dialog 50 times). If memory keeps growing and never drops, something leaks.
- Take two heap snapshots (before and after) and compare which objects grew. For Node, run node --inspect and open chrome://inspect.
setInterval(() => {
const mb = (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(1);
console.log('heap used:', mb, 'MB');
}, 5000);Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Memory and garbage collection · 1/6
In this lesson you will learn how JavaScript frees memory and how memory leaks happen.
Prefer a video by a teacher? Find free videos on “javascript memory leaks garbage collection heap snapshot” on YouTube ↗
In real life: A chat dashboard that slowed down by evening
A customer-support dashboard got slower through the day. Each time an agent opened a chat, the code added a setInterval to poll for messages but never cleared it when the chat closed. By evening, hundreds of timers were running. Clearing the interval on close fixed it.
function openChat(id, poll) {
const timer = setInterval(() => poll(id), 2000);
return function closeChat() { clearInterval(timer); }; // the fix: always clean up
}
const close = openChat('C-17', (id) => {});
close();Practice (0/2 done)
Write makeLimitedCache(max) that returns { set(key, value), get(key), size() }. When set makes the cache bigger than max, delete the OLDEST entry (Map keeps insertion order).
Write startPolling(fn, ms) that calls fn every ms milliseconds and returns a stop() function that clears the interval. The test checks that no calls happen after stop.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Node.js basicsPerformance and Node.js · same module
- Files and a tiny server in NodePerformance and Node.js · same module
- JVM memory and garbage collectionJava Programming (Core to Spring Boot) · Design patterns, JVM internals and interviews
- Memory 101: the stack and the heapRust Programming · Ownership: Rust's big idea
- Stack and heapC Programming (from zero to systems) · Dynamic memory
- What Rust is and why learn itRust Programming · Getting started with Rust
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
When can the garbage collector free an object?
Answer: When no reachable reference points to it
Reachability decides what is kept.
Which is a common memory leak?
Answer: A setInterval that is never cleared
The timer and everything its callback refers to stay alive.
Why use a WeakMap to attach data to DOM elements?
Answer: Entries disappear when the element is gone
Weak keys do not keep the element alive.
How can you spot a leak?
Answer: Memory keeps growing while repeating an action and never drops
Steady growth after repeated actions is the classic sign.
Which is the default garbage collector in modern JDKs?Related
How does Rust decide when to free heap memory?Related
Answer: Ownership rules let the compiler insert the free at the right point
Rust frees a value when its owner goes out of scope, decided at compile time.
Why use a WeakMap for a cache keyed by objects?Related
Answer: Entries do not keep the key objects alive
WeakMap entries disappear when the key object is no longer used elsewhere.
From Map and Set
Who frees heap memory in C?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Performance and Node.js” before its exam: Node.js basics, Files and a tiny server in Node, Real project tooling.
- Module 11 exam: Performance and Node.js · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Interview preparation and career. 61 topics left in the course before the final exam.