The Stack and the Heap
Both, the stack and the heap are parts of memory available to code at runtime. Each of them is structured in a particular way
The Stack
A stack is memory set aside for a thread of execution. Stacks are assembled in a certain order - blocks that enter last are removed first (= LIFO principle). Whenever stacks are accessed, it can only be done in a given order.
- Pushing data into the stack adds them on top
- Pop’ing data from the stack removes them from top again
Pros and cons of the stack
Stacks are more organized and faster to access. They are in turn accessible only in a given order - after the LIFO principle - and during a program’s runtime
Stack blocks Whenever a function is called, a block is reserved on top of the stack for local variables and bookkeeping data. When this function returns, the block is freed and can be reused. Stack blocks can point to data in the Heap
The Heap
The heap is memory set aside for dynamic allocation. It is assembled after no given pattern - any block can be allocated and freed at any time. That means: New data is not created on top, but at any point on the heap where there’s enough space. When the heap is accessed, it must be done with Pointers
Pros and cons of the heap
Data on the heap can be accessed in any given order and independently of running processes. It is in turn less efficient to use and takes more time to access.
Heap pointers Pointers are like adresses of locations in the heap. Each pointer ‘points’ to a space that holds allocated data.
Function Calls on the Heap
Let’s take Node.js as an example. When a Javascript file is executed, a new process is spawned. This process creates an event loop, which continously checks if there are functions that must be run and executes them in order.
The following code will be moved in the stack - and run - like so:
function logOne() {
console.log('one');
}
function logTwo() {
console.log('two');
}
function logBoth() {
console.log('go')
logOne();
logTwo();
}
logBoth();The first iteration:
- Add
logBothto the stack - Execute the first
console.log() - Return control to
logBoth
The second iteration:
- Add
logOneto the stack - Execute the
console.loginsidelogOne - Return control to
logOne - return control to
logBoth
The third operation is a replica of the second, just with logTwo()