operating systems30 min

Memory Management

How the OS and runtime allocate, use, and reclaim memory

0/9Not Started

Why This Matters

Every variable you create, every object you build, every function you call needs memory. But memory is finite. Your computer has a fixed amount of RAM, and if programs keep allocating without releasing, eventually the system grinds to a halt. Scope determines where a variable is visible in code, but memory management determines where a variable physically lives and when it gets cleaned up.

Understanding the call stack vs the heap, how garbage collection works, and what causes memory leaks gives you the power to write efficient programs and debug performance problems. When your web app slows down after running for hours, or your server's memory usage keeps climbing, memory management is the lens you need.

Define Terms

Visual Model

Stackgrows down
calculate()
main()
Code / Data
Heapgrows up
Object { name }
Array [1,2,3]
Garbage Collector
frees memory

The full process at a glance. Click Start tour to walk through each step.

Stack memory is fast and automatic (LIFO). Heap memory is flexible but requires garbage collection to reclaim.

Code Example

Code
// STACK: primitive values and function calls
function multiply(a, b) {
  const result = a * b; // result is on the stack
  return result;        // stack frame popped on return
}
multiply(3, 4);

// HEAP: objects and arrays
const user = { name: "Alice", age: 28 };  // on the heap
const numbers = [1, 2, 3, 4, 5];          // on the heap

// REFERENCE: stack variable points to heap object
let a = { x: 1 };
let b = a;       // b points to the SAME heap object
b.x = 2;
console.log(a.x); // 2 (same object!)

// MEMORY LEAK: forgotten event listeners
function setupHandler() {
  const hugeData = new Array(1000000).fill("data");
  
  // This closure captures hugeData, keeping it in memory
  // even after setupHandler returns
  document.addEventListener("click", () => {
    console.log(hugeData.length);
  });
  // Fix: remove the listener when no longer needed
}

// Check memory usage in Node.js
console.log(process.memoryUsage());
// { heapUsed: 4500000, heapTotal: 9000000, ... }

Interactive Experiment

Try these exercises:

  • In Node.js, run process.memoryUsage() before and after creating a large array. How much does heapUsed increase?
  • Create a closure that captures a large array. Does the array get garbage collected if you still hold a reference to the closure?
  • In Python, use sys.getrefcount(obj) to check the reference count of an object. Create another variable pointing to it and check again.
  • Intentionally create a memory leak by pushing items into a global array in a loop. Watch memory usage grow with process.memoryUsage().

Quick Quiz

Coding Challenge

Spot the Memory Leaks

The function `createLeakyApp` has three memory leaks. Write a function `createFixedApp` that fixes all three: (1) the listeners array grows unboundedly, (2) the cache object is never cleaned, and (3) the closures capture the entire `largeData` array. Your fixed version should: limit listeners to the last 10, limit cache to 100 entries (deleting the oldest when full), and not capture unnecessary data in closures.

Loading editor...

Real-World Usage

Memory management is critical in production systems:

  • Chrome's V8 engine uses a generational garbage collector that separates short-lived objects (nursery) from long-lived ones (old space) for optimal GC performance.
  • React manages component memory through mount/unmount lifecycle. Forgetting to clean up event listeners or timers in useEffect causes memory leaks.
  • Serverless functions (AWS Lambda) have strict memory limits. Exceeding them crashes your function immediately.
  • Mobile apps must be especially careful with memory because phones have less RAM. iOS will kill your app if it uses too much.
  • Redis and Memcached are purpose-built memory management systems that provide fast, bounded caching with configurable eviction policies.

Connections