Hunting JavaScript Memory Leaks: Chrome DevTools, Heap Snapshots & Event Listeners
Step-by-step methodology for diagnosing browser and Node.js memory leaks. Analyzing retained sizes, detached DOM trees, and uncleaned closures.

1. How JavaScript Garbage Collection Works (Mark-and-Sweep)
Modern JavaScript engines (V8, JavaScriptCore) use mark-and-sweep garbage collection algorithms. The engine starts at 'GC roots' (global variables, current call stack execution contexts) and traverses all reachable object references.
Any object that is unreachable is freed. A memory leak occurs when an object is no longer needed by application logic, but remains inadvertently reachable through a lingering reference.
2. The Top 3 Common Leak Sources in React & Vanilla JS
1. Forgotten Intervals & Timeouts: Calling `setInterval` inside a React component without clearing it in the `useEffect` cleanup return keeps the callback closure alive in memory forever.
2. Lingering Global Event Listeners: Attaching listeners to `window.addEventListener('resize', handler)` without calling `removeEventListener` retains both the handler and any parent scope variables.
3. Detached DOM Nodes: Storing a reference to an HTML element in a JavaScript variable after removing that element from the visible DOM keeps the entire subtree in memory.
import { useEffect } from "react";
export function useWindowResize(handler: () => void) {
useEffect(() => {
window.addEventListener("resize", handler);
// CRITICAL: Return cleanup function to detach listener on unmount
return () => {
window.removeEventListener("resize", handler);
};
}, [handler]);
}3. Mastering DevTools Heap Snapshots
Open Chrome DevTools > Memory tab. Take a baseline snapshot. Perform user actions in your application (e.g. open and close a modal dialog 10 times). Take a second snapshot and switch the view from 'Summary' to 'Comparison'.
Sort by '# Delta' and look for yellow and red objects. Red objects represent detached DOM trees held in memory by active references. Inspect the 'Retainers' tree at the bottom of the pane to pinpoint the exact variable preventing garbage collection.