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
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
// 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 doesheapUsedincrease? - 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
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.
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
useEffectcauses 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.