JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicsperformanceMemory Leaks & Management
PrevNext
performance
advanced
25 min read

Memory Leaks & Management

closures
detached-dom
devtools
event-listeners
finalization-registry
garbage-collection
heap-snapshots
memory-leaks
profiling
timers
weakmap
weakref

Memory leaks occur when JavaScript retains references to objects that are no longer needed, causing steadily increasing memory consumption that degrades performance and can eventually crash the browser tab.

Key Points

1Event Listener Leaks

Listeners not removed on cleanup keep their callbacks and closures alive. Always remove listeners when components unmount or elements are removed.

2Timer and Interval Leaks

setInterval runs indefinitely until cleared. Uncleared timers in unmounted components retain references to stale data and closures.

3Detached DOM Nodes

Removing a DOM element while keeping a JavaScript reference to it prevents the entire subtree from being garbage collected.

4DevTools Memory Analysis

Heap Snapshots compare allocations between actions, Allocation Timeline tracks persistent allocations, and Performance Monitor shows real-time heap growth.

5WeakMap and WeakRef

Weak references allow associated objects to be garbage collected, making them ideal for caches and metadata stores that should not prevent cleanup.

What You'll Learn

  • Identify the four most common sources of memory leaks in JavaScript applications
  • Use Chrome DevTools Heap Snapshots and Allocation Timeline to diagnose memory leaks
  • Apply WeakMap and WeakRef to build caches that do not prevent garbage collection
  • Implement cleanup patterns in React useEffect to prevent leaks on component unmount

Deep Dive

JavaScript uses automatic garbage collection — the engine periodically identifies objects that are no longer reachable from the root (global scope, call stack) and frees their memory. A memory leak occurs when objects that should be garbage collected remain reachable due to unintended references. Over time, this causes the heap to grow, the garbage collector to run more frequently, and eventually the page to slow down or crash.

Common Sources of Memory Leaks

Forgotten event listeners: Adding event listeners to DOM elements or global objects (window, document) without removing them is the most common leak. When a component unmounts or an element is removed, its listeners keep the callback — and everything in its closure — alive. Always call removeEventListener in cleanup code, or use { once: true } for one-time listeners. In React, return a cleanup function from useEffect.

Uncleared timers and intervals: setInterval callbacks run indefinitely until cleared with clearInterval. If you set up an interval in a component that unmounts without clearing it, the callback continues executing and retaining references to stale data. The same applies to setTimeout if the component unmounts before it fires.

Detached DOM nodes: When you remove a DOM element from the document but retain a JavaScript reference to it (in a variable, array, or Map), the entire DOM subtree remains in memory. This is especially common with caching patterns that store removed elements for potential reuse.

Closures capturing large scopes: A closure retains its entire lexical environment. If a small callback closes over a scope containing a large array or object, that entire scope stays in memory as long as the callback exists. This is subtle because the leak is not in the closure itself but in what the closure inadvertently captures.

Global variables: Accidentally creating global variables (forgetting let/const, or assigning to this in non-strict mode) attaches data to the window object, where it is never garbage collected.

Detection with DevTools

Chrome DevTools provides three key tools for memory analysis:

Heap Snapshots: Take a snapshot, perform an action, take another snapshot, and compare. Objects that appear in the second but not the first are potential leaks. Filter by "Objects allocated between snapshots" to find them.

Allocation Timeline: Records memory allocations over time. Blue bars that remain (never get garbage collected) indicate leaks. This helps identify which operations cause persistent allocations.

Performance Monitor: The real-time panel shows JS heap size, DOM nodes, and event listeners count. A steadily increasing heap or DOM node count during normal usage strongly indicates a leak.

WeakMap and WeakRef

WeakMap and WeakSet hold "weak" references to their keys — if the key object has no other references, it can be garbage collected even though it is in the WeakMap. This makes them ideal for associating metadata with objects without preventing their cleanup. WeakRef (ES2021) provides a weak reference to any object, and FinalizationRegistry lets you register a callback that fires when an object is garbage collected.

Prevention Patterns

Always clean up in useEffect return functions. Use AbortController to cancel fetch requests on unmount. Prefer event delegation over individual listeners. Use WeakMap for object-keyed caches. Avoid storing DOM references in long-lived data structures. In production, use automated memory monitoring to catch leaks before users do.

Key Interview Distinction

Memory leaks in JavaScript are not about unreleased memory in the traditional sense — the garbage collector handles that. They are about unintended references that prevent garbage collection. The fix is always to remove the reference: clear the timer, remove the listener, nullify the variable, or use weak references.

Fun Fact

JavaScript's garbage collector uses a 'mark-and-sweep' algorithm. It starts from root objects (global scope, call stack), marks everything reachable, then sweeps (frees) everything unmarked. V8's garbage collector is called Orinoco and can perform most of its work concurrently on a background thread, pausing the main thread for less than 1ms in most cases.

Learn These First

Closures

intermediate

Runtime Performance & Profiling

advanced

Continue Learning

Runtime Performance & Profiling

advanced

Performance Monitoring & Budgets

advanced

React Performance Optimization

intermediate

Practice What You Learned

How do you identify and fix memory leaks in JavaScript applications?
senior
memory
Use Chrome DevTools Memory tab to take heap snapshots and compare them over time. Common leaks include detached DOM nodes, forgotten event listeners, closures holding references, and uncleared timers. Fix by proper cleanup in useEffect, removing listeners, and using WeakMap.
Previous
Lazy Loading Techniques
Next
Core Web Vitals & Performance Metrics
PrevNext