JS Guide
HomeQuestionsSearchResources
Search

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

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsjavascript
PrevNext
javascript
senior
memory

How does JavaScript garbage collection work and how can you prevent memory leaks?

memory
garbage-collection
memory-leaks
performance
weakmap
Quick Answer

JavaScript uses automatic garbage collection with a mark-and-sweep algorithm. Objects are collected when unreachable from roots (global, stack). Memory leaks occur from uncleared references like closures, event listeners, intervals, and DOM references.

Detailed Explanation

Garbage Collection Basics:

  • JavaScript automatically manages memory
  • Uses mark-and-sweep algorithm (mostly)
  • Objects are collected when unreachable from 'roots'

Root References:

  • Global variables
  • Current call stack
  • Closures referencing variables

Common Memory Leaks:

  1. Forgotten timers/intervals: setInterval without clearInterval
  2. Detached DOM elements: JS references to removed DOM nodes
  3. Closures: Unintentionally capturing large scopes
  4. Event listeners: Not removed when elements are destroyed
  5. Global variables: Accidental globals via missing 'let/const'
  6. Circular references: (mostly handled by modern GC)

Prevention Strategies:

  • Use WeakMap/WeakSet for caches
  • Remove event listeners on cleanup
  • Clear intervals and timeouts
  • Nullify references when done
  • Use browser DevTools Memory profiler

Code Examples

Common memory leak patterns
// LEAK 1: Forgotten interval
function startPolling() {
  setInterval(() => {
    fetch('/api/data').then(updateUI);
  }, 1000);
  // Never cleared! Runs forever.
}

// FIX: Store and clear
let pollInterval;
function startPolling() {
  pollInterval = setInterval(/* ... */);
}
function stopPolling() {
  clearInterval(pollInterval);
}

// LEAK 2: Event listeners not cleaned up
class Component {
  constructor() {
    window.addEventListener('resize', this.handleResize);
  }
  // Missing cleanup! Listener persists after component destroyed.
}

// FIX: Add destroy method
class Component {
  constructor() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  }
  destroy() {
    window.removeEventListener('resize', this.handleResize);
  }
}

Resources

MDN - Memory Management

docs

Chrome DevTools - Fix memory problems

article
Previous
What are Proxies in JavaScript and how can they be used?
Next
Explain the Module pattern and how ES6 modules differ from CommonJS.