Skip to content
intermediatePhase 33 · Advanced JavaScript

Memory Management

Prevent memory leaks by understanding references, closures, and event cleanup.

45m
0 problems
Topic Progress0%

Memory Lifecycle

Every program follows the same memory lifecycle:

Three Stages

// 1. ALLOCATION - Memory is allocated for use
const obj = { name: 'Alice' }; // Heap memory allocated
const arr = [1, 2, 3]; // Array buffer allocated

// 2. USAGE - Memory is used
console.log(obj.name); // Read from memory
arr.push(4); // Write to memory

// 3. RELEASE - Memory is freed
obj = null; // Mark for garbage collection
// GC will eventually free the memory

JavaScript Memory Model

// Stack (primitive values, fixed size)
let x = 10; // Stored in stack
let y = 'hello'; // Stored in stack

// Heap (objects, dynamic size)
let obj = { name: 'Alice' }; // Object in heap, reference in stack
let arr = [1, 2, 3]; // Array in heap, reference in stack

// When you copy a reference
let obj2 = obj; // Both point to same object in heap
obj2.name = 'Bob';
console.log(obj.name); // 'Bob' (shared reference!)

Memory Limits

// Browsers typically limit heap size
// Chrome: ~1-4GB depending on system
// You can check in DevTools: Performance > Memory

// Exceeding limits causes errors
try {
  const hugeArray = new Array(1000000000);
} catch (e) {
  console.error('Out of memory:', e.message);
}

Common Memory Leaks

Memory leaks occur when objects are no longer needed but still referenced.

1. Accidental Global Variables

function createLeak() {
  leakedVariable = 'I am leaked!'; // No var/let/const!
  // This creates a global variable that's never freed
}

// Fix: Always use var, let, or const
function noLeak() {
  const notLeaked = 'I am safe!';
}

2. Forgotten Event Listeners

function setup() {
  const button = document.getElementById('btn');
  button.addEventListener('click', () => {
    console.log('clicked');
  });
  // If button is removed, listener is still attached!
}

// Fix: Remove listeners when done
function cleanup() {
  const button = document.getElementById('btn');
  button.removeEventListener('click', handler);
}

3. Forgotten Timers

function start() {
  setInterval(() => {
    // This keeps running!
    updateUI();
  }, 1000);
  // No way to stop it!
}

// Fix: Store reference and clear
let intervalId;
function start() {
  intervalId = setInterval(updateUI, 1000);
}
function stop() {
  clearInterval(intervalId);
}

4. Closures Holding References

function createClosure() {
  const largeData = new Array(1000000).fill('data');
  
  return function() {
    // This closure holds reference to largeData
    console.log('closure called');
  };
}

const closure = createClosure();
// largeData stays in memory as long as closure exists

// Fix: Release reference when not needed
closure = null;

5. Detached DOM Nodes

let element;
function create() {
  element = document.createElement('div');
  document.body.appendChild(element);
}
function remove() {
  document.body.removeChild(element);
  // element still references the detached node!
}

// Fix: Nullify reference
function remove() {
  document.body.removeChild(element);
  element = null;
}

Prevention Strategies

Strategies to prevent memory leaks in JavaScript applications.

1. Use Strict Mode

'use strict';

function leak() {
  leaked = 'error!'; // ReferenceError!
}

2. Nullify References

// When done with large objects
let largeData = fetchHugeData();
processData(largeData);
largeData = null; // Allow GC to collect

3. Remove Event Listeners

function setup() {
  const handler = () => console.log('clicked');
  button.addEventListener('click', handler);
  
  return () => {
    button.removeEventListener('click', handler);
  };
}

const cleanup = setup();
// Later:
cleanup();

4. Clear Timers

const intervals = [];

function startPolling() {
  const id = setInterval(poll, 1000);
  intervals.push(id);
}

function stopAll() {
  intervals.forEach(clearInterval);
  intervals.length = 0;
}

5. WeakRef and FinalizationRegistry (ES2021)

let weakRef = new WeakRef(targetObject);

// Access the object (may be garbage collected)
const obj = weakRef.deref();
if (obj) {
  // Object still exists
  console.log(obj.data);
}

// FinalizationRegistry for cleanup
const registry = new FinalizationRegistry((heldValue) => {
  console.log('Object collected:', heldValue);
});

registry.register(obj, 'my-object');

6. Memory Profiling

// Chrome DevTools Memory tab
// 1. Take heap snapshot
// 2. Compare snapshots
// 3. Look for detached nodes, increasing objects

// Code for profiling
console.log('Before:', performance.memory.usedJSHeapSize);
// Run operation
console.log('After:', performance.memory.usedJSHeapSize);

7. Object Pooling

const pool = [];

function getObject() {
  return pool.pop() || createObject();
}

function releaseObject(obj) {
  obj.reset(); // Clean up
  pool.push(obj);
}

// Use
const obj = getObject();
// ... use object ...
releaseObject(obj);

Practice Problems

0/3solved
Build Memory Management Component

Create a reusable React component implementing Memory Management. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Memory Management Testing

Write unit and integration tests for Memory Management using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Memory Management Performance

Optimize Memory Management for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What is a memory leak?

Question 1 options

2. Which is a common cause of memory leaks?

Question 2 options

3. How do you prevent memory leaks from closures?

Question 3 options

4. What is WeakRef used for?

Question 4 options

Flashcards

Question

What is a memory leak?

Answer

When objects are no longer needed but still referenced, preventing garbage collection from freeing the memory.

Question

How to prevent memory leaks?

Answer

Nullify references, remove event listeners, clear timers, use strict mode, profile with DevTools.

Question

What is the memory lifecycle?

Answer

1. Allocation (memory allocated), 2. Usage (memory used), 3. Release (memory freed by GC).

Question

What is WeakRef?

Answer

A reference that doesn't prevent garbage collection. Object can be collected even if WeakRef exists.

Question

What is Memory Management?

Answer

Memory Management is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.Memory lifecycle: allocation → usage → release
  • 2.Common leaks: globals, listeners, timers, closures, DOM nodes
  • 3.Always nullify references when done with large objects
  • 4.Remove event listeners when elements are removed
  • 5.Use DevTools Memory tab to detect leaks

Interview Tips

  • Explain the memory lifecycle and garbage collection
  • Discuss common memory leaks and how to prevent them
  • Show how to profile memory in Chrome DevTools
  • Explain WeakRef and when to use it

Cheat Sheet

Memory Management Cheat Sheet

Memory Lifecycle

  1. Allocation: Memory assigned
  2. Usage: Memory accessed
  3. Release: GC frees memory

Common Leaks

  • Accidental globals (no var/let/const)
  • Forgotten event listeners
  • Forgotten timers/intervals
  • Closures holding large objects
  • Detached DOM nodes

Prevention

  • Use strict mode
  • Nullify references when done
  • Remove event listeners
  • Clear timers
  • Use WeakRef for caches
  • Profile with DevTools

Memory Model

  • Stack: Primitives, fixed size
  • Heap: Objects, dynamic size