LESSON 04 · BEGINNER4 min read

Memory Allocation, The Heap & Mark-and-Sweep Garbage Collection

Inspect the memory lifecycle. Explore primitive stack allocation, heap memory graphs, reference reachability, and V8's Mark-and-Sweep garbage collector.

ES2024 / Node.js 20+Free to readModule 1 of 10
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Distinguish between Stack allocation (fixed size, fast) and Heap allocation (dynamic, graph-based).
  • Understand reference reachability from roots (Global object, Call Stack).
  • Explain V8's generational garbage collection (Orinoco, Scavenger, Mark-and-Sweep).

01The Three Stages of the Memory Lifecycle

Regardless of the programming language you use, the memory lifecycle follows three fundamental steps: allocate the memory you need, use the allocated memory (reading and writing values), and release the memory when it is no longer needed. In low-level languages like C and C++, developers must manually invoke malloc() and free() to manage this lifecycle. A forgotten free() causes memory leaks, while freeing too early causes catastrophic memory corruption.

JavaScript is a garbage-collected language. The engine automatically allocates memory whenever you create variables, objects, functions, or arrays, and it automatically releases that memory when those values are no longer reachable. However, 'automatic' does not mean 'magic': understanding how memory is partitioned between the Stack and the Heap is vital to building high-performance, non-leaking applications.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02The Stack vs The Heap

The JavaScript engine divides memory into two primary zones: the Call Stack and the Memory Heap. The Stack is used for static, contiguous memory allocation. Primitive values (numbers, booleans, undefined, symbols, null) whose size is fixed and known at compile time are stored directly within stack frames. Accessing stack memory is blazingly fast because the CPU merely increments or decrements the stack pointer.

The Heap is a large, unstructured region of memory dedicated to dynamic allocation. Objects, arrays, closures, and functions have arbitrary, variable sizes that can mutate at runtime. When you instantiate an object, V8 allocates a chunk of heap memory to hold the object's properties. It then stores the memory address (a reference pointer) on the Stack. When you assign an object to another variable, you are copying the pointer on the stack, not the underlying heap data.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03Mark-and-Sweep and Generational GC

How does V8 determine which heap allocations can be safely freed? Modern engines use the Mark-and-Sweep algorithm based on the concept of reference reachability. The collector defines a set of 'Roots': the global execution context, active call stack frames, and active DOM nodes. Periodically, the garbage collector starts at these roots and traverses every outgoing reference pointer, recursively marking every reachable object as 'alive'.

Once traversal concludes, the 'Sweep' phase begins: any heap memory allocation that was not marked as reachable is deemed garbage and reclaimed. To optimize this process, V8 employs Generational Garbage Collection: most objects die young. It divides the heap into a Young Generation (frequently collected via fast Scavenge algorithms) and an Old Generation (objects that survive multiple collection cycles and are collected via full Mark-Sweep-Compact cycles).

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Why This Matters in Production

Accidental memory leaks in client-side Single Page Applications (SPAs) and Node.js backend microservices almost always happen when developers inadvertently leave reachable references to objects that are no longer needed. Examples include forgetting to remove global event listeners, leaving active setInterval timers running, or retaining large arrays inside long-lived closures.

Because the root maintains a path of references to the object, Mark-and-Sweep considers it alive, preventing V8 from releasing it. Over hours or days, heap consumption steadily climbs until the container crashes with an Out-Of-Memory (OOM) error.

LET IT CLICK

The ideas worth keeping.

  • Primitive values reside on the Call Stack; dynamic objects and arrays are allocated on the Heap.
  • Variables holding objects store reference pointers, meaning assignment copies the pointer, not the object.
  • Mark-and-Sweep reclaims memory by traversing from roots; unrooted allocations are swept automatically.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Exercise 1: Breaking Unreachable Object Cycles

Write a function that breaks circular references between two objects so they become eligible for garbage collection when the parent reference is removed.

your_turn_1.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
function unlinkCircular(nodeA, nodeB) {  nodeA.neighbor = null;  nodeB.neighbor = null;}

Although modern Mark-and-Sweep handles circular references between unrooted objects, explicitly clearing cross-references ensures isolated nodes are collected promptly.

02

Exercise 2: Safe Cache with Weak References

Explain why using WeakMap instead of Map prevents memory leaks when caching metadata for dynamic object keys.

your_turn_2.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
// Using WeakMap allows keys to be garbage collected when no other references exist:const metadataCache = new WeakMap();function tagObject(obj, meta) {  metadataCache.set(obj, meta);}

WeakMap holds weak references to its keys. When an object key has no other live references in the application, V8 can garbage-collect it and its associated value automatically.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01Where are dynamic objects and arrays allocated in JavaScript memory?
02How does the Mark-and-Sweep garbage collection algorithm identify dead memory?
03What is a primary cause of client-side memory leaks in Single Page Applications?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Exercise 1: Breaking Unreachable Object Cycles

Write a function that breaks circular references between two objects so they become eligible for garbage collection when the parent reference is removed.

EXPECTED OUTPUT
[Process exited with code 0 - No output]
main.jsJavaScript
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this lesson, when you want a second angle or the full details.

MODULE 01 · PRACTICAL SELF-CHECK

Pause. Put the pieces together.

You’ve reached the end of How JavaScript Runs: Engines, Memory & Execution. Before moving on, use this task to check what you can do independently.

Correctly predict execution order, stack frames, and TDZ boundaries across sample programs.

Try it in your own environment and write down the result. This is a self-check; reading completion does not evaluate your code.

Review this module

One lesson closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock lesson completion.