Heap vs Stack in JavaScript Memory
The JavaScript engine (e.g., V8) divides memory into two main sections:
- Call Stack — stores function execution contexts and primitive data types.
- Heap — stores reference type objects, functions, and arrays.
When you declare variables, different memory sections are used depending on the data type.
// Stack - primitive types
let age = 30;
let isOnline = true;
// Heap - reference types
let user = {
name: "Ani",
age: 25
};
When you pass a primitive variable to a function, it's passed by value, while objects are passed by reference.
function updateAge(a) {
a = 40;
}
let myAge = 30;
updateAge(myAge);
console.log(myAge); // 30 - primitive => value copy
function updateUser(obj) {
obj.age = 40;
}
let person = { age: 30 };
updateUser(person);
console.log(person.age); // 40 - reference => direct modify
Advantages of understanding Heap vs Stack:
- Helps understand variable behavior in functions
- Essential for writing performant code
Tips for Efficient Memory Management
While JavaScript automatically manages memory (we don't write free() or delete as in C), we can contribute to efficiency by:
- Using
constwhere no changes are needed - Cleaning up timers, intervals, sockets, and observers when no longer needed
- Using WeakMap and WeakSet when storing objects without interfering with GC
- Removing DOM event listeners in componentWillUnmount or useEffect cleanup
// WeakMap – weak reference, GC can free the object
let cache = new WeakMap();
function process(user) {
if (!cache.has(user)) {
cache.set(user, computeHeavy(user));
}
return cache.get(user);
}
Why use WeakMap/WeakSet:
- They don't "hold" objects but allow GC to remove them when no other references exist
- Useful for caches, observer patterns, and attaching metadata