The more you know, the more you don’t know, the more like and see, the hand left fragrance, and have glory

The introduction

The JS memory space is divided into stack, heap, and pool (usually also categorized as stack).

The stack stores variables, the heap stores complex objects, and the pool stores constants, so it is also called the constant pool.

Stack data structure

A stack is a special kind of list. The elements in the stack can only be accessed through one end of the list, called the top of the stack. A stack is said to be a last-in-first-out (LIFO) data structure. Since the stack is last in, first out, any element that is not at the top of the stack is not accessible. To get at the bottom of the stack, you must first remove the top element.

Here, for the convenience of understanding, through the analogy of ping-pong box to analyze the stack access mode.

This ping-pong ball is stored in the same way as the stack access data. Table tennis 5, which is at the top of the box, must be put in last, but can be used first. And if we want to use table tennis 1 on the bottom, we have to take the top four table tennis balls out, so that table tennis 1 is on the top of the box. This is the stack space first in, last in, first out characteristics.

Heap data structure

A heap is a sorted, tree-shaped data structure where each node has a value. Usually what we call the data structure of the heap is the binary heap. A heap is characterized by the minimum (or maximum) value of the root node, and the two subtrees of the root node are also a heap. Because of this feature, the heap is often used to implement a priority queue. The access to the heap is arbitrary, just like when we take books from the library shelves. Although the books are placed in order, we do not need to take out all the previous books as the stack does, we only need to care about the name of the book.

The relationship between variable types and memory

Basic data type

There are six basic data types:

  1. Sting
  2. Number
  3. Boolean
  4. null
  5. undefined
  6. Symbol

Basic data types are stored in stack memory because they are small, fixed in size, accessed by value, and are frequently used data.

To better understand the basic data type variables and stack memory, we use the following example and diagram to understand:

let num1 = 1;
let num2 = 1;
Copy the code

PS: It is important to note that the basic data type variables in closures are not held in stack memory, but in heap memory. We’ll come back to that later.

Reference data type

Array,Function,Object… You can think of all types as reference data types except the basic data types mentioned above.

Reference data types are stored in the heap memory because they take up a large space and are not fixed in size. If stored on the stack, the performance of the program will be affected. The reference data type stores a pointer on the stack to the starting address of the entity in the heap. When the interpreter looks for a reference value, it first retrieves its address in the stack and then retrieves the entity from the heap

To better understand variable objects and heap memory, let’s combine the following examples and diagrams.

// Basic data type - stack memory
let a1 = 0;
// Basic data type - stack memory
let a2 = 'this is string';
// Basic data type - stack memory
let a3 = null;

// The pointer to the object is stored in stack memory, and the object to which the pointer points is stored in heap memory
let b = { m: 20 };
// The pointer to the array is stored in stack memory, and the array to which the pointer points is stored in heap memory
let c = [1.2.3];
Copy the code

So when we want to access a reference data type in the heap, we actually first get the address pointer to that object from the variable and then get the data we need from the heap.

Variable replication from a memory perspective

Replication of basic data types

let a = 20;
let b = a;
b = 30;
console.log(a); // What is the value of a, 30? Or two?
Copy the code

The answer is: 20

In this example, a and B are both basic types, and their values are stored in the stack memory. A and B each have their own stack space, so the value of a does not change after changing the value of B.

The following figure clearly shows how variables are copied and modified.

Replication of reference data types

let m = { a: 10.b: 20 };
let n = m;
n.a = 15;
console.log(m.a) // What is the value of m.a, which is 10? Or 15?
Copy the code

The answer is: 15

In this case, m, n is a reference type, stack memory storage address pointing to the object in the heap memory, the replication of a reference type as new variables automatically assigns a new value stored in the variable, but it’s just a reference type address pointer, actually refer to the same object, so after modifying n.a. value, The m.A. changed accordingly.

The following figure clearly shows how variables are copied and modified.

Advantages and disadvantages of stack memory and heap memory

In JS, basic data type variables are fixed in size and easy to manipulate, so they are stored on the stack. Reference type variables don’t have a fixed size, so allocate them to the heap and let them determine their size as they apply for space. Storing them separately minimizes the amount of memory your program needs to run.

Because of its characteristics, the stack memory system efficiency is higher. Heap memory needs to allocate space and addresses, and store addresses on the stack, so it is less efficient than the stack.

Garbage collection of stack memory and heap memory

A variable in stack memory is usually destroyed by garbage collection at the end of its current execution environment, while a variable in heap memory is not, because it is uncertain if there are references to it elsewhere. A variable in the heap is only reclaimed when all references to it have ended.

See another article (Memory Management in JS) for details on garbage collection.

Closures and heap memory

Variables in closures are not held in stack memory, but in heap memory. This explains why closures can refer to variables within a function even after the function has been called.

Let’s first look at what closures are:

function A() {
  let a = 1;
  function B() {
      console.log(a);
  }
  return B;
}
let res = A();
Copy the code

Function A returns A function B that uses A variable of function A, and function B is called A closure.

After function A pops the call stack, the variables in function A are stored on the heap, so function B can still refer to the variables in function A. Today’s JS engines can use escape analysis to identify which variables need to be stored on the heap and which need to be stored on the stack.

Article Series

  • “Front-end advanced” single-page route resolution and implementation
  • “Front-end progression” thoroughly understand function currying
  • Memory management in “front-end advanced” JS
  • The front-end advanced array is out of order

reference

  • JavaScript advanced programming
  • Memory space detailed diagram

Write in the last

  • Feel free to correct any mistakes in the comments section, and if this post helped you, feel free togive a likeandFocus on
  • This article was published simultaneously withgithub, can be ingithubTo find more articles, welcomeWatch & Star u
  • For a follow-up article, see Planning

Welcome to pay attention to the wechat public number [front small black house], every week 1-3 high-quality high-quality articles push, to help you go up the ladder journey