Does JavaScript use stack or heap for memory allocation or both?

Does JavaScript uses stack or heap for memory allocation or both, I know it uses heap for achieving closures. But does it also use stack. What are the use cases for what it uses and when it uses?

Comments (12)

Add a comment
Marco Alka's photo

First of all, JavaScript is based on the ECMA-262 standard, which does not define memory layout, so whatever it uses depends on how the interpreter is implemented.

Stack vs Heap

When talking about stack and heap, it is imperative to make sure we talk about the same stuff. So let me start by explaining what stack and heap are, how they differ, and when they are usually used in classic system-languages, like C. Basically, modern languages, like Rust, still roughly follow those principles, but might deviate in order to optimize run-time performance.

Stack

A stack is a region in memory, which operates in First-In-Last-Out mode. One can imagine it as a pile of paper sheets. When you put a piece of paper on a table and put another piece of paper on top, you first have to take the upper piece of paper up in order to take the first one up (you are only allowed to take one piece of paper at a time). When a new thread is started by a computer program (usually the main thread first ;) ), a new stack is created. It is small and can be used to quickly store and retrieve temporary data. In C, The stack is usually used for low-cost data, like simple data types (integer, float, pointer (which is also just an integer),...) to keep it speedy and prevent a stack-overflow.

Heap

The heap, which is also called "free store", is a large region in memory, which can be used to store arbitrary data in an unordered fashion. That's why it's a lot slower, and used for data structures in classic languages, like C. A lot of science went into optimizing the way space is allocated in heap, so that there is a minimum number of gaps in between data. In order to quickly find heap-data when doing operations, a pointer to it is stored on the stack.

So, where are variables allocated

Since it is not standardized, the interpreter developers have leeway to play around and write complex optimizations. So, let's take a look at V8!

The easiest way is to think for a second. Javascript is a garbage-collected language. GC means that there is data scattered around which has to be cleaned up. Does that sound like the data is stored on the stack? Rather... no, because the stack has strictly ordered data. So, variables are allocated on the heap.

The most direct way to find out how V8 handles things so is to take a look at the actual source code (hooray for opensource!). In order to find out the basic data type, I used the NodeJS unofficial V8 reference, and looked up how to pass a Boolean value around inside V8. In order to do so, a class called "Boolean" is used. Whenever I use a boolean value, that class is instantiated. Well, basically that's C++ land. C++, like C, stores data structures on the heap and only works with pointers to it in the stack. So, whenever V8 has to allocate a new variable, it allocates a structure holding the data plus additional information on the heap (so much for the answer to your original question). What's interesting is what the optimizer does later on, because if a variable is always used as a boolean, it might as well drop the structure and use it as a boolean on the stack, which would bring us to system-performance without all that soft abstraction stuff on top.

Show all replies
Marco Alka's photo

Software Engineer & Mentor

Mohit Singh

tl;dr: JS is single-threaded. You do not need any of your considerations.


It is known that NodeJs is a single thread programming language

NodeJS is a JS runtime, not a language. JavaScript is the language. JavaScript, at least at of the moment of writing, is single-threaded. However, NodeJS has an event-loop and can offload tasks to it's internal thread pool or the Kernel, so that it can execute code while it waits for IO - which allows NodeJS to handle many requests simultaneously, even though it is single-threaded.

if any variable [..] is called by different threads

JavaScript is single-threaded, hence a variable cannot be used from several threads. There is only one execution thread per NodeJS instance, which is driven by an event-loop.

I am confused if it was corrupting the stack or the heap.

I don't think that a request can corrupt the stack or the heap. To make things simple for you: JavaScript does allocate everything on the heap in order to run GC on the memory regions easily.

I am also using lock in my NodeJs project, only for a critical code section

I am not sure you know what you are doing. Mutexes are generally good to sync data submissions in JS, especially over the network. If you are in a NodeJS program and not doing order-dependent data submissions over an unreliable channel, then you do not need mutexes. JavaScript is single-threaded. If you need to wait for an async operation to finish, use async/await.

Satya's photo

To be short, V8 uses a heap similar to JVM, local variables are put on the stack and objects in the heap. Consider this code,

function foo(b) { var a = 10; return a + b + 11; }

function bar(x) { var y = 3; return foo(x * y); }

console.log(bar(7));

When we call bar() it will create a frame in stack with name bar and with respective arguments and when it ends it gets to pop out from stack, There really was no recursion in my code, if it has "Maximum call stack size exceeded" exception will be thrown, so stack frame is used in this way of memory allocation. I think most of the global variables use heap and it appears when memory leaks occur

HazNode's photo

The simple answer is: Heap. But it doesn't really matter because:

  1. JS is a dynamic language and as such memory allocation happens dynamically.
  2. JS has loose typing which generally makes it less useful to keep data on the stack. I'm sure the VM uses the stack when it sees fit though.
  3. The stack and heap concept stem from the early days of processors when memory was more or less statically allocated and the stack was typically accessed using a fast 1 opcode instruction as opposed to 3-4 opcodes for a heap or direct memory access. Modern CPU architectures work differently and don't really make a huge difference between stacks and heaps. As long as there is no cache-miss, performance difference should be minor if not negligible. In reality it comes down to how good or bad the the VM is at realtime optimisation and memory management.
Kamil Tomšík's photo

Stack is freed automatically at the end of call unlike heap which has to be garbage collected, which in turn can (and will if we're talking about long-running node.js app) cause "stop-the-world" problem