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

View original thread
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.