ðŸ§
Memory Model
intermediateJavaScript uses two memory regions: the Stack for primitives and function calls, and the Heap for objects and dynamic data. Understanding this helps you predict performance, avoid memory leaks, and understand how garbage collection works.
🎮Interactive Visualization
Code
1// Primitives (stored in Stack)2let a = 10;3let b = a;4b = 20;56// Objects (stored in Heap)7let obj1 = { x: 1 };8let obj2 = obj1;9obj2.x = 99;1011console.log(a, obj1.x);
Stack
(empty)
Heap
(empty)
Step 1/8Script starts. Stack is empty.
Key Insight: Primitives are copied by VALUE (independent). Objects are copied by REFERENCE (shared)!
Key Points
- Stack: stores primitives (numbers, booleans, strings) and function call frames
- Heap: stores objects, arrays, and functions (dynamic allocation)
- Variables hold references (pointers) to heap objects, not the objects themselves
- Garbage Collection: V8 uses mark-and-sweep to free unreachable objects
- Memory leaks occur when objects remain referenced but are no longer needed
💻Code Examples
Primitives vs Objects
// Primitives stored in stack
let a = 10;
let b = a; // Copy of value
b = 20;
console.log(a); // 10 (unchanged)
// Objects stored in heap
let obj1 = { x: 1 };
let obj2 = obj1; // Copy of reference
obj2.x = 99;
console.log(obj1.x); // 99 (same object!)Primitives are copied by value, objects by reference
Stack Frames
function outer() {
let x = 1; // Frame 1
inner();
}
function inner() {
let y = 2; // Frame 2
// Stack: [global, outer, inner]
}
outer();
// inner() returns → frame popped
// outer() returns → frame poppedEach function call creates a stack frame
Heap Allocation
// Each {} creates new heap object
function createUser(name) {
return {
name: name,
data: new Array(1000)
};
}
let user1 = createUser("Alice");
let user2 = createUser("Bob");
// Two separate objects on heapObjects allocated on heap persist until GC
Garbage Collection
let obj = { data: "important" };
// obj is reachable → NOT collected
obj = null;
// Original object now unreachable
// GC will reclaim this memory
// in next collection cycleUnreachable objects are garbage collected
Memory Leak
const cache = [];
function processData(data) {
// BUG: cache grows forever!
cache.push(data);
return data.value * 2;
}
// Fix: limit cache size or use WeakMap
const weakCache = new WeakMap();Unbounded caches cause memory leaks
Closures & Memory
function createCounter() {
let count = 0; // Kept alive by closure
return () => ++count;
}
const counter = createCounter();
// 'count' lives in heap as long
// as 'counter' function existsClosures keep variables alive on heap
Common Mistakes
- Thinking primitives and objects are stored the same way
- Forgetting that object assignment copies references, not values
- Creating memory leaks with event listeners, closures, or global caches
- Not understanding that garbage collection is non-deterministic
Interview Tips
- Draw stack and heap diagrams for given code
- Explain why === behaves differently for primitives vs objects
- Know common memory leak patterns and how to fix them
- Understand WeakMap/WeakSet for cache scenarios