Home  >  Article  >  Web Front-end  >  Summary of garbage collection knowledge of JavaScript hidden mechanism

Summary of garbage collection knowledge of JavaScript hidden mechanism

WBOY
WBOYforward
2022-06-08 16:11:262691browse

This article brings you relevant knowledge about javascript, which mainly introduces the issues related to garbage collection. Garbage collection is the hidden mechanism of JavaScript. Let’s take a look at it together. I hope it will be helpful to everyone. helpful.

Summary of garbage collection knowledge of JavaScript hidden mechanism

[Related recommendations: javascript video tutorial, web front-end]

1. Preface

Garbage collection is the hidden mechanism of JavaScript. We usually don’t need to work hard for garbage collection, we only need to focus on the development of functions. But this does not mean that we can sit back and relax when writing JavaScript. As the functions we implement become more and more complex and the amount of code accumulates, performance problems become more and more prominent. . How to write code that executes faster and takes up less memory is the never-ending pursuit of programmers. An excellent programmer can always achieve amazing results with extremely limited resources. This is also the difference between ordinary beings and aloof gods.

2. What is garbage

Code is executed in the computer’s memory, and all variables, objects, and functions we define in the code will occupy a certain amount of memory space in the memory. In computers, memory space is a very tight resource. We must always pay attention to the memory usage. After all, memory modules are very expensive! A variable, function, or object can be called garbage if it is no longer needed for subsequent code execution after creation.

Although it is very easy to understand the definition of garbage intuitively, for a computer program, it is difficult for us to conclude at a certain moment that the currently existing variables, functions or objects will no longer be used in the future. In order to reduce the cost of computer memory and ensure the normal execution of computer programs, we usually stipulate that objects or variables that meet any of the following conditions are garbage:

  1. No referenced objects or variables;
  2. Inaccessible objects (circular references between multiple objects);

Unreferenced variables or objects are equivalent to a house without a door, we can never enter it, so It's impossible to use them anymore. Although inaccessible objects are connected, they are still inaccessible from the outside and therefore cannot be used again. Objects or variables that meet the above conditions will never be used again in the future execution of the program, so they can be safely treated as garbage collection.

When we clarify the objects that need to be discarded through the above definition, does it mean that there is no garbage in the remaining variables and objects?

no! The garbage we currently identify is only a part of all garbage. There will still be other garbage that does not meet the above conditions, but it will not be used again.

Can we say that the garbage that meets the above definition is "absolute garbage", and other garbage hidden in the program is "relative garbage"?

3. Garbage Collection

The garbage collection mechanism (GC, Garbage Collection) is responsible for recycling useless variables and memory space occupied during program execution. The phenomenon that an object still exists in memory even though it has no possibility of being used again is called Memory leak. Memory leaks are a very dangerous phenomenon, especially in long-running programs. If a program has a memory leak, it will occupy more and more memory space until it runs out of memory.

Strings, objects, and arrays do not have fixed sizes, so dynamic storage allocation can only be performed when their sizes are known. Every time a JavaScript program creates a string, array, or object, the interpreter allocates memory to store the entity. Whenever memory is allocated dynamically like this, it must eventually be freed so that it can be used again; otherwise, the JavaScript interpreter will consume all available memory in the system, causing the system to crash.

JavaScript's garbage collection mechanism will intermittently check for useless variables and objects (garbage) and release the space they occupy.

4. Reachability

Different programming languages ​​adopt different garbage collection strategies. For example, C has no garbage collection mechanism. All memory management relies on The programmer's own skills have also resulted in the current situation that C is relatively difficult to master. JavaScriptUse reachability to manage memory. Literally speaking, reachability means that it can be reached, which means that the program can access and use variables and objects in some way. , the memory occupied by these variables cannot be released.

JavaScript specifies an inherent set of reachable values, and the values ​​in the set are inherently reachable:

  1. The context of the function currently being executed (including local variables within the function, parameters of the function, etc.);
  2. Other functions on the current nested call chain, their local variables and parameters;
  3. Global variables;
  4. Other internal variables;

The above variables are called root, which is the top node of the reachability tree.

If a variable or object is directly or indirectly used by the root variable, the variable is considered reachable.

In other words, if a value can be accessed through the root (for example, A.b.c.d.e), then this value is reachable.

5. Examples of reachability

Hierarchical association:

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};

The above code creates an object and assigns it to the variable people , the variable people contains two objects boys and girls, boys and girls It also contains two sub-objects. This also creates a data structure containing the 3 layer reference relationship (without considering the basic type data), as shown below:

Summary of garbage collection knowledge of JavaScript hidden mechanism

Among them, the people node is naturally reachable because it is a global variable. The boys and girls nodes are indirectly reachable because they are directly referenced by global variables. boys1, boys2, girls1 and girls2 are indirectly applied by global variables and can be passed through people.boys.boysAccess, so it is also a reachable variable.

If we add the following code after the above code:

people.girls.girls2 = null;people.girls.girls1 = people.boys.boys2;

Then, the above reference hierarchy diagram will become the following form:

Summary of garbage collection knowledge of JavaScript hidden mechanism

Among them, girls1 and girls2 have become unreachable nodes due to disconnection from the grils node, which means they will be recycled by the garbage collection mechanism. .

If at this time, we execute the following code:

people.boys.boys2 = null;

Then the reference hierarchy diagram will become the following form:
Summary of garbage collection knowledge of JavaScript hidden mechanism

At this time, although The boys node and the boys2 node are disconnected, but because there is a reference relationship between the boys2 node and the girls node, boys2 is still reachable and will not be recycled by the garbage collection mechanism.

The above association diagram proves why the equivalent value of global variables is called root, because in the association diagram, this type of value usually appears as the root node of the relationship tree.

Interrelated:

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};people.boys.boys2.girlfriend = people.girls.girls1;	
    //boys2引用girls1people.girls.girls1.boyfriend = people.boys.boys2;	//girls1引用boys2

The above code creates an interrelated relationship between boys2 and girls1, relationship structure diagram As follows:

Summary of garbage collection knowledge of JavaScript hidden mechanism

At this point, if we cut off the association between boys and boys2:

delete people.boys.boys2;

The relationship diagram between objects is as follows:

Summary of garbage collection knowledge of JavaScript hidden mechanism

Obviously, there are no unreachable nodes.

At this time, if we cut off the boyfriend relationship connection:

delete people.girls.girls1;

The relationship diagram becomes:

Summary of garbage collection knowledge of JavaScript hidden mechanism

This At this time, although there is still a girlfriend relationship between boys2 and girls1, boys2 and becomes an unreachable node and will be garbage Recycling mechanism takes back.

Accessible island:

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};delete people.boys;delete people.girls;

The reference hierarchy diagram formed by the above code is as follows:

Summary of garbage collection knowledge of JavaScript hidden mechanism

At this time, Although there are still mutual reference relationships between objects inside the dotted box, these objects are also unreachable and will be deleted by the garbage collection mechanism. These nodes have become disconnected from the root and become unreachable.

6. Garbage collection algorithm

Reference counting

The so-called reference counting, as the name suggests, is to count every time an object is referenced. When a reference is added, it is increased by one, and when a reference is deleted, it is decreased by one. If the number of references becomes 0, it is considered garbage, and the object is deleted to reclaim the memory.

For example:

let user = {username:'xiaoming'};
//对象被user变量引用,计数+1
let user2 = user;
//对象被新的变量引用,计数+1
user = null;
//变量不再引用对象,计数-1
user2 = null;
//变量不再引用对象,奇数-1
//此时,对象引用数为0,会被删除

Although the reference counting method seems very reasonable, in fact, there are obvious loopholes in the memory recycling mechanism using the reference counting method.

For example:

let boy = {};	
let girl = {};	
boy.girlfriend = girl;
girl.boyfriend = boy;
boy = null;
girl = null;

以上代码在boygirl之间存在相互引用,计数删掉boygirl内的引用,二者对象并不会被回收。由于循环引用的存在,两个匿名对象的引用计数永远不会归零,也就产生了内存泄漏。

C++中存在一个智能指针shared_ptr)的概念,程序员可以通过智能指针,利用对象析构函数释放引用计数。但是对于循环引用的状况就会产生内存泄漏。

好在JavaScript已经采用了另外一种更为安全的策略,更大程度上避免了内存泄漏的风险。

标记清除

标记清除mark and sweep)是JavaScript引擎采取的垃圾回收算法,其基本原理是从出发,广度优先遍历变量之间的引用关系,对于遍历过的变量打上一个标记(优秀员工徽章),最后删除没有标记的对象。

算法基本过程如下:

  1. 垃圾收集器找到所有的,并颁发优秀员工徽章(标记);
  2. 然后它遍历优秀员工,并将优秀员工引用的对象同样打上优秀员工标记;
  3. 反复执行第2步,直至无新的优秀员工加入;
  4. 没有被标记的对象都会被删除。

举个栗子:

如果我们程序中存在如下图所示的对象引用关系:

Summary of garbage collection knowledge of JavaScript hidden mechanism

我们可以清晰的看到,在整个图片的右侧存在一个“可达孤岛”,从出发,永远无法到达孤岛。但是垃圾回收器并没有我们这种上帝视角,它们只会根据算法会首先把根节点打上优秀员工标记。

Summary of garbage collection knowledge of JavaScript hidden mechanism

然后从优秀员工出发,找到所有被优秀员工引用的节点,如上图中虚线框中的三个节点。然后把新找到的节点同样打上优秀员工标记。

Summary of garbage collection knowledge of JavaScript hidden mechanism

反复执行查找和标记的过程,直至所有能找到的节点都被成功标记。

Summary of garbage collection knowledge of JavaScript hidden mechanism

最终达到下图所示的效果:

Summary of garbage collection knowledge of JavaScript hidden mechanism

由于在算法执行周期结束之后,右侧的孤岛仍然没有标记,因此会被垃圾回收器任务无法到达这些节点,最终被清除。

如果学过数据结构和算法的童鞋可能会惊奇的发现,这不就是图的遍历吗,类似于连通图算法。

七、性能优化

垃圾回收是一个规模庞大的工作,尤其在代码量非常大的时候,频繁执行垃圾回收算法会明显拖累程序的执行。JavaScript算法在垃圾回收上做了很多优化,从而在保证回收工作正常执行的前提下,保证程序能够高效的执行。

性能优化采取的策略通常包括以下几点:

分代回收

JavaScript程序在执行过程中会维持相当量级的变量数目,频繁扫描这些变量会造成明显的开销。但是这些变量在生命周期上各有特点,例如局部变量会频繁的创建,迅速的使用,然后丢弃,而全局变量则会长久的占据内存。JavaScript把两类对象分开管理,对于快速创建、使用并丢弃的局部变量,垃圾回收器会频繁的扫描,保证这些变量在失去作用后迅速被清理。而对于哪些长久把持内存的变量,降低检查它们的频率,从而节约一定的开销。

增量收集

增量式的思想在性能优化上非常常见,同样可以用于垃圾回收。在变量数目非常大时,一次性遍历所有变量并颁发优秀员工标记显然非常耗时,导致程序在执行过程中存在卡顿。所以,引擎会把垃圾回收工作分成多个子任务,并在程序执行的过程中逐步执行每个小任务,这样就会造成一定的回收延迟,但通常不会造成明显的程序卡顿。

Idle collection

CPUEven in complex programs, there is no work all the time, mainly becauseCPU The work speed is very fast, and the peripheral IO is often several orders of magnitude slower, so arranging a garbage collection strategy when the CPU is idle is a very effective performance optimization method, and it is basically not necessary. It will have a negative impact on the program itself. This strategy is similar to the system's idle time upgrade, and users are not aware of the background execution at all.

8. Summary

The main task of this article is to simply end garbage collection mechanisms, commonly used strategies and optimization methods. It is not intended to give everyone an in-depth understanding of the background execution principles of the engine.

Through this article, you should understand:

  1. Garbage collection is one of the features of JavaScript. It is executed in the background and we don’t need to worry about it;
  2. The strategy of garbage collection is mark removal, which filters and removes garbage according to the reachability theory;
  3. The clear mark strategy can avoid memory leaks caused by reachable islands

[Related recommendations :javascript video tutorialweb front-end

The above is the detailed content of Summary of garbage collection knowledge of JavaScript hidden mechanism. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete