Writing in the front

How does the browser parse the JS code we write? What happens when the browser executes JS code? … These questions may not be important in the process of completing the business function code, but as a front-end developer, understanding them will improve my thinking and give me a deeper understanding of the JavaScript language. This article will detail the underlying handling of stack memory in browsers, the garbage collection mechanism, and several cases of memory leaks.

What does the browser go through to execute code

compile

  • Lexical parsing: This process breaks down a string of characters into meaningful code blocks (lexical units).

  • Parsing: This process converts lexical unit streams into a hierarchical nested tree of elements that represents the program syntax (abstract syntax tree => AST).

  • Code generation: The process of converting an AST into executable code is called code generation.

The engine compiles the execution code

Then hand the built code to the engine (V8), which may encounter variable promotion, scope and scope chain/closure, variable objects, stack memory, GO/VO/AO/EC/ECStack,… .

When the engine compiles the execution code, it first creates an execution stack, known as stack memory (ECStack => execution environment stack), and then executes the code.

An EC(execution context) is created during code execution. The execution context is divided into global execution context (EC(G)) and function execution context (EC(…). ), where the execution context of a function is private.

During the creation of an execution context, you might create:

  • GO(Global Object)The global object browser side assigns GO to the window
  • VO(Varible Object): variable object that stores variables in the current context.
  • AO(Active Object): Active object

The created context is then pushed onto the stack for execution, unused contexts are pushed off the stack after execution, and useful contexts are squeezed to the bottom of the stack (closures). The bottom of the stack is always the global execution context, and the top is always the current execution context.

The following diagram illustrates the entire process

The three-step operation of variable assignment

The first step is to create a variable, a process called declare.

Second, create the value. Primitive type values are created and stored directly on the stack; Due to the complex structure of reference type values, it is necessary to create a memory space to store the key-value pairs in the object (store the code in the function). This memory is the heap memory, and all the heap memory has a hexadecimal address that can be searched later. The subsequent association assignment is to give the heap memory address to the variable operation.

The final step is to associate variables with values, a process called definition. In this case, the value is undefined if it is only declared and no assignment is performed.

Understand the process in one question

I’m going to show it as a drawing

/ / 1.

let a = 12;

let b = a;

b = 13;

console.log(a);



/ / 2.

let a = {n:12};

let b = a;

b['n'] = 13;

console.log(a.n);



/ / 3.

let a = {n:12};

let b = a;

b = {n:13};

console.log(a.n);

Copy the code
  • The first question

Create the execution stack to form the global execution context, and create GO to enter the stack to execute the code

Basic types are created and stored directly on the stack

So the final output of this question is 12.

  • The second question

Create the execution stack to form the global execution context, and create GO to enter the stack to execute the code

Reference type values are complex, and heap memory will be created

So the final output of this question is a.n = 13

  • The third question

Create the execution stack to form the global execution context, and create GO to enter the stack to execute the code

Reference type values are complex, and heap memory will be created

So the final output of this question is a.n of 12.

A few interview questions will give you a deeper understanding of the underlying processing of the browser stack memory

  • The first question
let a = {

    n10

};

let b = a;

b.m = b = {

    n20

};

console.log(a);

console.log(b);

Copy the code

Create the execution stack to form the global execution context, and create GO to enter the stack to execute the code

Reference type values are complex, and heap memory will be created

So the final output a is {n: 10, m: {n: 20}}; B: {n: 20}

  • Second question:
let x = [12.23];

function fn(y{

    y[0] = 100;

    y = [100];

    y[1] = 200;

    console.log(y);

}

fn(x);

console.log(x);

Copy the code

The ECStack is created to form the global execution context, VO(variable object) is created, and the code is executed on the stack

Variable assignment

The fn(x) function is then executed, and the function execution forms a new execution context, producing the AO. As I said, the top of the stack is always the current execution context, and the bottom of the stack is the global execution context, so the function executes, the function execution context pushes up, pushes the global execution context down the stack.

The code is then executed, and the stack is removed after execution

Go ahead and print x after the above analysis:

The answer is: [100, 200] [100, 23]

  • The third question
var x = 10;

function (x{

    console.log(x);

    x = x || 20 && 30 || 40;

    console.log(x);

} ();

console.log(x);

Copy the code

So, the final result is: undefined 30 10

  • The fourth question
let x = [1.2].

    y = [3.4];

function (x{

    x.push('A');

    x = x.slice(0);

    x.push('B');

    x = y;

    x.push('C');

    console.log(x, y);

}(x);

console.log(x, y);

Copy the code

So the subject for the final output results [3, 4, ‘C’] [3, 4, ‘C’] [1, 2, ‘A’] [3, 4, ‘C’].

Garbage collection mechanism

Javascript in browsers has automatic Garbage Collecation, where the Garbage collector periodically (periodically) finds variables that are no longer in use and then frees their memory.

Mark clear

In JS, the most common garbage collection mechanism is tag cleanup: variables are marked “in” when they enter the execution environment, and “out” when they leave the execution environment. The garbage collector destroys the tagged values and reclaims the memory they occupy.

function demo({

    var a = 1;     // mark "enter environment"

    var b = 2;     // mark "enter environment"





demo();            // when the function completes, a and B are marked "out of the environment"

Copy the code

Reference counting

The browser keeps track of the number of references to the value. For each additional reference, the number of references is increased by 1. When the value is removed, the number of references is decreased by 1.

The following example illustrates the change in the number of references to A

function demo({

    var a = {};     / / + 1

    var b = a;      / / + 1 = > 2

    b = null;       / / - 1 = > 1

    a = null;       // -1 => 0 ====> This command is recycled

}

Copy the code

A memory leak

Memory leak refers to that the memory space that should be released after some functions or tasks are executed in the program is not released due to various reasons, resulting in more and more memory consumption of the program, which may eventually lead to various serious consequences such as program crash.

There are four common memory leaks in JS

The global variable

An example directly illustrates:

 var obj = null

 function foo(){

      obj = { name:"Little red" }; 

 }

 foo();

Copy the code

In the above code, obj is a global variable, so that all functions at the same level of scope as obj can access obj objects, so obj objects are not recycled.

closure

Closures are the most leak-prone feature of JS

function foo(){

    var obj = {name:"Little red"}

    return function(){

         return obj.name;

    }

}

var func = foo();   // foo returns a function, and func becomes an external function

func();             // The external function func can access the user object inside foo.

Copy the code

In the above code, the variable obj is not released because func() can still access obj after foo is executed. This causes a memory leak, which we can fix with the following method

function foo(){

    var obj = {name:"Little red"}

    return function(){

        var obj1 = obj;

        obj = null;

        return obj1.name;

    }

}

var func = foo();   // foo returns a function, and func becomes an external function

func();          

Copy the code

In the above code, obj is freed in time in the function returned by foo, and the local variable obj is not accessed when the func function executes.

References to DOM elements

Memory leaks occur in references to DOM elements

  • DOMThe element is deleted, butJSThe reference in the object is not deleted
<body>

    <div id="app"></div>

    <script>

        var appDom = document.getElementById("app");



        appDom.onclick = function({

            document.body.removeChild(document.getElementById("app"));

        }

    
</script>

</body>

Copy the code

In the example above, when #app is clicked, the DOM node is cleared, but appDom still keeps the reference to it, causing #app not to be released.

  • Use third-party libraries

The timer

The setInterval timer cycles until it is cleared manually, which is a memory hazard, so it should be cleared when the timer runs out.

var count = setInterval((a)= > {

    console.log(1);

}, 1000);



// Complete

clearInterval(count)

Copy the code

The above are the four cases that lead to memory leaks (not only the examples in this article, there will be many examples in daily development work), in our daily development work, we should avoid these four cases, so we write code in the process, should pay more attention to.

conclusion

This article detailed how stack memory is handled in the browser, and briefly discussed several methods of garbage collection mechanisms and several situations that can cause memory leaks. Also hope that after careful reading (automatically ignore my ugly word 🐶), can point out the unreasonable and even wrong place, we learn together, common progress ~

Finally, share my public number “Web front-end diary”, I hope you pay more attention to