debugjavascriptMajor
Detecting memory leaks with Chrome DevTools heap snapshots
Viewed 0 times
memory leakheap snapshotChrome DevToolsgarbage collectionretained objectssetInterval leakevent listener leak
chrome
Error Messages
Problem
The application's memory usage grows over time without a clear cause. Long-running sessions become slow or crash. The source of the leak is not obvious from code inspection.
Solution
Use the Chrome DevTools Memory panel with heap snapshots to pinpoint retained objects.
// Common patterns that cause leaks:
// 1. Event listeners not removed
const handler = () => processData();
window.addEventListener('resize', handler);
// FIX: window.removeEventListener('resize', handler);
// 2. Timers not cleared
const id = setInterval(poll, 1000);
// FIX: clearInterval(id) on cleanup
// 3. Closures holding large objects
function createCache() {
const bigData = new Array(1000000).fill('x');
return () => bigData.length; // bigData is retained
}
- Open DevTools > Memory > Heap snapshot
- Take Snapshot 1 (baseline)
- Perform the suspected leaking action several times
- Force garbage collection (trash icon)
- Take Snapshot 2
- Switch to Comparison view, filter by 'Delta' descending
- Look for unexpectedly growing object types
// Common patterns that cause leaks:
// 1. Event listeners not removed
const handler = () => processData();
window.addEventListener('resize', handler);
// FIX: window.removeEventListener('resize', handler);
// 2. Timers not cleared
const id = setInterval(poll, 1000);
// FIX: clearInterval(id) on cleanup
// 3. Closures holding large objects
function createCache() {
const bigData = new Array(1000000).fill('x');
return () => bigData.length; // bigData is retained
}
Why
The heap snapshot comparison shows objects allocated between two points in time that were not garbage collected. Objects retained despite being logically 'done' point to unintentional references keeping them alive.
Gotchas
- Always force GC before taking a snapshot — retained objects after GC are true leaks
- WeakMap and WeakRef allow objects to be GC'd; use them for caches keyed by DOM nodes or objects
- React: missing useEffect cleanup (return () => ...) is a top source of leaks in SPA navigation
- The Allocation Timeline view shows which call stacks are allocating memory over time
Code Snippets
WeakRef cache that does not prevent garbage collection
// Use WeakRef for caches to avoid memory leaks
const cache = new Map();
function getCachedResult(key, obj) {
if (cache.has(key)) {
const ref = cache.get(key);
const cached = ref.deref();
if (cached) return cached;
}
const result = expensiveCompute(obj);
cache.set(key, new WeakRef(result));
return result;
}Context
When investigating slow performance or out-of-memory crashes in long-running browser sessions
Revisions (0)
No revisions yet.