Parsin’ the Interruption: How Javascript Handles Memory

Parsin’ the Interruption: How Javascript Handles Memory

As you all know, JavaScript parses and executes code separately. As the code is scanned, memory is set aside for each object it comes across.

But how much memory is allocated for each object? Is it decided on the spot? Is there some predetermined amount of memory set aside for each element?

These are questions I was wondering myself. And when I asked around I mostly heard that the same amount of memory is set aside for everything — which was confusing. How could a variable with an assignment of a string be allocated the same amount of memory as a function with five or ten variables? It can’t. And it isn’t. But, before I continue let me say this: the term memory can be understood in different scopes and have different applications and meanings depending on those scopes. For example, you can talk about memory in terms of how many bytes are needed to store a value, you can talk about it in terms of functional memory like stacks and heaps, or you can talk about it in terms of the amount of memory a program borrows from its operating system or server. There are various other contexts that change the meaning of memory in relation to the language you’re exploring. So it’s easy to not be on the same page as someone when you’re discussing memory.

The bottom line, at least for my question is this. JavaScript has two types of memory, static and dynamic. Each comports to its own space— the stack and the heap. So let me hash that out.

Static => Stack

Dynamic => Heap

The stack is where scalar primitive values (Number, String, Boolean, undefined, null, Symbol) are held. A scalar primitive value is one that is passed and assigned ‘by value’.

The heap is much larger area where compound values (objects, arrays, functions requiring user input). A compound value is one that is passed and assigned ‘by reference’.

In JavaScript, the prototypes for scalar primitive values are immutable whereas compound values are mutable. Immutable means you can’t change the value, when you reassign the same value to a new variable and change the value, you are changing a copy of the value that was made on reassignment.

Let me say that again…

You can assign a number to a variable, assign another variable to the first variable, change the value of one variable and not affect the value assignment of the other.

This is because when you assign the second variable to the first, you are actually assigning it to a copy of the value that the variable points at, and not the variable itself or the value itself. It creates a new copy of the value and stores it. So each of the variables point to distinct values. That is the main characteristic of variables assigned and passed by value in the stack.

On the other hand with assign-by-reference, if you assign a variable to an array, a reference is created that is shared by any variable that is pointed to it.

When the compound value in a variable is reassigned, a new reference is created. In JavaScript, unlike in most other popular programming languages, the references are pointers to values stored in variables and NOT pointers to other variables, or references.

This difference in assignment by value and reference is what Dan Abramov was talking about in his famous tweet, and it is ultimately reflected by the lower level difference of memory allocation during the parsing phase.

So, this answered my question about the difference in how variables were parsed. Static variables, or variables passed by value, are saved in the stack — a temporary, Last In First Out, data structure. And like a “stack” of plates, every time a function is called, it is placed onto the stack, called a “stack frame”.

Then every time a function exits, all of the declarations placed on the stack by that function, are “freed”. This freeing, or deleting, of a stack frame means that the region of memory is now available for other stack variables. But more importantly, this is the physical representation of scope. The stack determines your local scope, and is responsible for closing it out upon the exit of a function.

The heap is extra storage independent of the stack, with no particular layout. It is responsible for compound variables and variables of unknown size. Objects on the heap live on after we exit the function, and are mainly disposed of by JavaScript’s garbage collector.

If you take anything away from this article it should be that Javascript has two different types of memory: static and dynamic. Each has its own memory space: stack and heap. The behaviors of variables are determined during parsing by whether they are assigned by value or assigned by reference. And the scopes of a program are reflected in the stack frames.

Leave a Reply

Your email address will not be published. Required fields are marked *

Book a consultation

Where are you trying to go? Book an introductory meeting to gain clarity on your personal or business needs.