Heap
The Heap is an unstructured memory region where objects, functions, closures, and dynamically allocated data are stored. Unlike the stack, heap memory is managed by garbage collection and has no automatic cleanup.
Stack vs Heap Memory
Section titled “Stack vs Heap Memory”flowchart LR subgraph Stack["Stack Memory (Fast, Limited)"] S1["Primitives\n(number, string, boolean)"] S2["References to heap objects"] S3["Function call frames"] end
subgraph Heap["Heap Memory (Slower, Large)"] H1["Objects {}"] H2["Arrays []"] H3["Functions () => {}"] H4["Closures"] H5["DOM Elements"] end
Stack -->|"references"| HeapHeap Memory Management
Section titled “Heap Memory Management”// Stack vs Heap allocationlet primitiveNumber = 42; // Stored on Stacklet primitiveString = "hello"; // Stored on Stacklet primitiveBoolean = true; // Stored on Stacklet primitiveNull = null; // Stored on Stacklet primitiveUndefined = undefined; // Stored on Stack
let object = { // Stored on Heap name: "JavaScript", // Reference stored on Stack year: 1995,};
let array = new Array(1000); // Stored on Heaplet function_ = function () {}; // Stored on Heap
// Heap memory allocation patternsfunction demonstrateHeap() { // These all allocate memory on the heap const obj1 = { a: 1, b: 2, c: 3 }; const obj2 = new Object(); const arr1 = [1, 2, 3, 4, 5]; const arr2 = new Array(1000000); const date = new Date(); const regex = /pattern/g; const map = new Map(); const set = new Set();
// Closures capture heap references let counter = 0; return function () { return counter++; // 'counter' persists in heap via closure };}
// Garbage collection exampleslet reference = { data: new Array(1000000) };reference = null; // Eligible for garbage collection
// WeakRef for non-critical referenceslet weakRef = new WeakRef({ data: "temporary" });console.log(weakRef.deref()); // May be undefined if GC ran
// WeakMap and WeakSet for automatic cleanupconst weakMap = new WeakMap();let obj = { id: 1 };weakMap.set(obj, "metadata");obj = null; // Both key and value can be garbage collectedHeap Memory Monitoring
Section titled “Heap Memory Monitoring”// Monitor heap usage (Chrome/Node.js)if (performance.memory) { setInterval(() => { console.log({ totalHeap: (performance.memory.totalJSHeapSize / 1048576).toFixed(2) + " MB", usedHeap: (performance.memory.usedJSHeapSize / 1048576).toFixed(2) + " MB", heapLimit: (performance.memory.jsHeapSizeLimit / 1048576).toFixed(2) + " MB", }); }, 5000);}
// Node.js heap statisticsif (typeof global.gc === "function") { const heapStats = process.memoryUsage(); console.log({ rss: (heapStats.rss / 1048576).toFixed(2) + " MB", heapTotal: (heapStats.heapTotal / 1048576).toFixed(2) + " MB", heapUsed: (heapStats.heapUsed / 1048576).toFixed(2) + " MB", external: (heapStats.external / 1048576).toFixed(2) + " MB", });}
// Detect memory leaksclass MemoryLeakDetector { constructor() { this.interval = null; this.baseline = null; }
start() { this.baseline = process.memoryUsage().heapUsed; this.interval = setInterval(() => { const current = process.memoryUsage().heapUsed; const growth = (((current - this.baseline) / this.baseline) * 100).toFixed(2);
if (growth > 50) { console.warn(`⚠️ Memory growth detected: ${growth}% increase`); } }, 10000); }
stop() { clearInterval(this.interval); }}
const detector = new MemoryLeakDetector();// detector.start();Common Heap Problems
Section titled “Common Heap Problems”// 1. Memory Leak - Global cache never clearedlet globalCache = new Map();function memoryLeak() { const largeData = new Array(1000000).fill("data"); globalCache.set(Date.now(), largeData); // Never cleared - LEAK}
// 2. Detached DOM elements (browser)function detachedDOMLeak() { let element = document.createElement("div"); document.body.appendChild(element); // Element removed from DOM but still referenced element.remove(); // 'element' still references the DOM node - LEAK // Fix: element = null;}
// 3. Event listeners not removedfunction eventListenerLeak() { const element = document.getElementById("button"); function handler() { console.log("clicked"); } element.addEventListener("click", handler); // Listener never removed - LEAK if element stays in memory // Fix: element.removeEventListener('click', handler);}
// 4. Closures holding large datafunction closureLeak() { const hugeArray = new Array(1000000).fill("data"); return function () { // Returns reference to hugeArray return hugeArray.length; };}const leaked = closureLeak(); // hugeArray never released
// Proper cleanup patternsfunction properCleanup() { // Use local references that go out of scope const largeData = new Array(1000000).fill("data"); processData(largeData); // No external reference - eligible for GC}
function processData(data) { // Process and discard console.log(data.length);}