Memory Management & Garbage Collection
JavaScript automatically manages memory through garbage collection, but you can still cause memory leaks. Understanding how memory works helps you write efficient code and avoid common leak patterns.
Memory Management
- Memory lifecycle — Allocate → Use → Release. JS handles allocate and release automatically
- Garbage Collection (GC) — Mark and Sweep algorithm. If object is unreachable, it's collected
- Reachable — Variable in scope, referenced by another reachable object, in the call stack
- Memory leak — Memory that should be freed but isn't. Accumulates over time → slowdown/crash
- Common leaks — Forgotten timers, detached DOM nodes, closures, global variables, event listeners
- WeakRef/WeakMap — Weak references don't prevent GC. Good for caches
Memory Management Code
// Memory is allocated automatically
let user = { name: "Alice", data: new Array(1000).fill("x") };
// Memory allocated for object + array
// GC collects when unreachable
user = null; // Object becomes unreachable → GC will collect it
// ❌ Memory Leak: forgotten timer
let leakyData = new Array(10000).fill("leak");
// const id = setInterval(() => {
// console.log(leakyData.length); // leakyData can't be GC'd
// }, 1000);
// Fix: clearInterval(id) when done
// ❌ Memory Leak: event listeners on removed elements
function addListener() {
const button = document.createElement("button");
button.addEventListener("click", () => {
console.log("Clicked!");
});
// If button is removed from DOM without removing listener = leak
// Fix: button.removeEventListener or use { once: true }
}
// ❌ Memory Leak: closures holding large data
function createProcessor() {
const hugeData = new Array(1000000).fill("x"); // stays in memory!
return function process() {
return hugeData.length; // closure keeps hugeData alive
};
}
// Fix: Only close over what you need, not the entire dataset
// ✅ Using WeakMap for caches
const cache = new WeakMap();
function processUser(user) {
if (cache.has(user)) return cache.get(user);
const result = { processed: true, name: user.name.toUpperCase() };
cache.set(user, result);
return result;
}
let alice = { name: "Alice" };
processUser(alice); // cached
alice = null; // WeakMap allows GC! (unlike regular Map)
console.log("Memory management best practices demonstrated");Tip
Tip
Take heap snapshots in DevTools > Memory before and after an action to detect leaks. Growing heap size across repeated actions indicates a leak. Compare snapshots to find which objects are accumulating.
Use Chrome DevTools Memory tab to detect leaks
Common Mistake
Warning
Storing references to DOM elements that get removed. If you remove a DOM element but keep a reference to it in a variable or array, the garbage collector can't free that memory. Clear references when elements are destroyed.
Practice Task
Note
Memory management: (1) Create and fix a closure-based memory leak. (2) Use WeakRef and FinalizationRegistry for cache entries. (3) Profile an app's memory usage in DevTools.
Quick Quiz
Key Takeaways
- JavaScript automatically manages memory through garbage collection, but you can still cause memory leaks.
- Memory lifecycle — Allocate → Use → Release. JS handles allocate and release automatically
- Garbage Collection (GC) — Mark and Sweep algorithm. If object is unreachable, it's collected
- Reachable — Variable in scope, referenced by another reachable object, in the call stack