Front end tips: JS garbage collection mechanism

catalogue

1, What is garbage collection

2, Principle of garbage collection mechanism

3, Waste recycling method

3.1 reference count

3.2 mark removal

Common memory leaks and Solutions

4.1 global variables:

4.2 timer and callback function  

4.3 closure  

4.4 DOM element references are not cleared:  

1, What is garbage collection

Garbage collection is an automatic memory management mechanism. When the dynamic memory on the computer is no longer needed, it should be released to make room for memory. To put it bluntly, the program runs in memory. When declaring a variable and defining a function, it will occupy memory. The capacity of memory is limited. If variables and functions only produce but do not die, sooner or later the memory will be fully occupied. At this time, not only their own programs cannot run normally, but also other programs will be affected. For example, creatures only have birth and no death. The earth will be burst one day. Therefore, in the computer, we need garbage collection. It should be noted that "automatic" in the definition means that the language can help us recycle memory garbage, but it does not mean that we do not need to care about memory management. If we do not operate properly, memory overflow will still occur in JavaScript.

2, Principle of garbage collection mechanism

Garbage collection is based on two principles:

1. Consider that a variable or object will not be accessed in future program runs

2. Ask these objects to return memory

The most important and difficult part of these two principles is to find that "the allocated memory is really no longer needed".

3, Waste recycling method

Now, there are two methods of garbage collection commonly used by major browsers: mark removal and reference counting.

3.1 reference count

This is the most elementary garbage collection algorithm (used by old browsers: IE). The strategy of reference counting is to track the number of times each value is used. When a variable is declared and a reference type is assigned to the variable, the number of references to the value is increased by one. If the value of the variable becomes another, the number of references to the value is reduced by one. When the number of references to the value is 0, it means that no variable is in use and the value cannot be accessed. Thus, the space occupied by these garbage collectors can be recycled. These garbage collectors will clean up the space occupied by the value with reference times of 0 at runtime, but this method is easy to cause memory leakage. Because this method does not solve the problem of circular reference, it is not recommended to use it!

function fun4(){
var obj = {}//Reference type variable, reference count of c is 0
var o = obj; //Obj is o referenced, and the reference count of obj is 1
var m = obj; //Obj is m referenced, and the reference count of obj is 2
o = {}  //o no longer reference obj, and the reference count of obj is reduced to 1
m = null //m no longer references obj, and the reference count of obj is reduced to 0
}

But there are some problems with reference counting: circular references

function fun5(){

	var f = {};
	var g = {};
	f.userName = g;
	g.userName = f;
	//Because f and g refer to each other, the count can never be 0

}

3.2 mark removal

This is the most commonly used garbage collection method in javascript. When a variable enters the execution environment, it is marked as "entering the environment". Logically, the memory occupied by variables entering the environment can never be released, because they may be used as long as the execution flow enters the corresponding environment. When a variable leaves the environment, it is marked as "leaving the environment".

When the garbage collector runs, it marks all variables stored in memory. It then removes the variables in the environment and the tags referenced by the variables in the environment. After that, the marked variables will be regarded as the variables to be deleted, because the variables in the environment can no longer access these variables. last. The garbage collector completes the memory cleanup, destroys the marked values, and reclaims the memory space they occupy.

function fun3(){
var a = 1;
var b = 2;
//When the function is executed, ab is marked respectively and enters the environment
}
fun3()  End of function execution, ab Marked out of the environment and recycled

But be careful

function fun1(){
	var obj = {}
}
function fun2(){
	var obj = {}
	return obj;
}
var a = fun1();
var b = fun2();
fun1 Execute as obj A block of memory is allocated, but as the function execution ends, obj The occupied space is released
fun2 When executed, it is also obj Memory was allocated, but due to obj
 Finally, it is returned to the assigned value b It is still used, so fun2 Medium obj The occupied memory will not be released
  • Common memory leaks and Solutions

  • 4.1 global variables:


function foo() {
  this.bar2 = 'Default binding this Point to global' // Global variable = > window.bar2
  bar = 'global variable'; // The undeclared variable is actually a global variable = > window.bar
}
foo();

Solution: use strict mode inside the function==>Strict mode prohibition this Keyword points to a global object

function foo() {
  "use strict"; 
  this.bar2 = "In strict mode this point undefined"; 
  bar = "report errors";
}
foo();

4.2 timer and callback function  


When not needed setInterval perhaps setTimeout The timer is not activated clear,Callback of timer
 Functions and internally dependent variables cannot be recycled, resulting in memory leakage.

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
        // The timer is not cleared
    }
    // node and someResource store a large amount of data and cannot be recycled
}, 1000);

Solution: when the timer completes its work, manually clear the timer.

4.3 closure  


Closures can maintain local variables in functions so that they cannot be released, resulting in memory leakage.
function bindEvent() {
  var obj = document.createElement("XXX");
  var unused = function () {
      console.log(obj,'Reference within closure obj obj Will not be released');
  };
  // obj = null;
}
Solution: dereference manually, obj = null. 

4.4 DOM element references are not cleared:  

var refA = document.getElementById('refA');
document.body.removeChild(refA); // dom deleted
console.log(refA, "refA");  // However, there are still references that can console out that the whole div has not been recycled

terms of settlement: refA = null;

Tags: Javascript Front-end

Posted on Wed, 27 Oct 2021 01:42:38 -0400 by subkida