Home >Web Front-end >JS Tutorial >JavaScript garbage collection mechanism analysis_javascript skills

JavaScript garbage collection mechanism analysis_javascript skills

WBOY
WBOYOriginal
2016-05-16 17:20:23959browse

In the company, I often hear experts talking about memory leaks during discussions, and I am always amazed. Recently, my energy has been mainly spent on Web development. I read "JavaScript Advanced Programming" (the book has a very good title). It's bluffing. The author actually wrote it very well. He learned about the JavaScript garbage collection mechanism from the simple to the deep and gained a certain understanding of memory leaks.

Like C# and Java, JavaScript has an automatic garbage collection mechanism, which means that the execution environment will be responsible for managing the memory used during code execution. There is no need to consider memory allocation and recycling of useless memory during the development process. The mechanism of JavaScript garbage collection is very simple: find the variables that are no longer used, and then release the memory they occupy. However, this process is not time-consuming because it is expensive, so the garbage collector will periodically collect the data at fixed intervals. implement.

Variable life cycle

Some students will ask after reading the above, what is a variable that is no longer used? Variables that are no longer used are variables whose life cycle has ended. Of course, they can only be local variables. The life cycle of global variables will not end until the browser unloads the page. Local variables only exist during the execution of the function, and during this process, corresponding space will be allocated for local variables on the stack or heap to store their values, and then these variables will be used in the function until the end of the function (closure Due to internal functions, external functions cannot be considered the end. To understand closures, you can look at JavaScript scope chain and what exactly is JavaScript closure).

Once the function ends, local variables are no longer necessary and the memory they occupy can be released. Why does a cat and a very simple job cost a lot of money? This is just the tip of the iceberg of garbage collection. Just like the closure just mentioned, it seems that the function has ended, but in fact it has not. The garbage collector must swim in that variable. That variable is useless, and it marks the variables that are no longer useful. Prepare for future recycling. There are many strategies for marking useless, and there are two common methods

mark and sweep

This is the most common garbage collection method in JavaScript. When a variable enters the execution environment, such as declaring a variable in a function, the garbage collector marks it as "entering the environment". When the variable leaves the environment (function execution ends ) marks it as "leaving the environment". As for how to mark, there are many ways, such as inverting special bits, maintaining a list, etc. These are not important. What is important is what strategy is used. In principle, the memory occupied by variables entering the environment cannot be released. They may occur at any time. will be called.

The garbage collector will mark all variables stored in memory at runtime, and then remove variables in the environment and variables (closures) referenced by variables in the environment. After these are completed, the mark will still exist The variables are to be deleted, because the variables in the environment can no longer access these variables, and then the garbage collector will occupy the space occupied by these marked variables.

Most browsers use this method for garbage collection. The difference lies in how to mark and the garbage collection interval. There is only a low version of IE, and as expected, it is IE again. . .

reference counting

Memory leaks often occur in lower versions of IE, often because they use reference counting for garbage collection. 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 1. If the value of the variable changes to another , then the number of references to this value is reduced by 1. When the number of references to this value becomes 0, it means that no variables are in use, and this value cannot be accessed, so the space it occupies can be recycled, so that the garbage collector will When running, the space occupied by the value with a reference count of 0 is cleared.

It looks like a good method, but why are so few browsers adopting it? Does it also cause memory leaks? Mainly because this method cannot solve the circular reference problem. For example, object A has an attribute pointing to object B, and object B also has an attribute pointing to object A, so they refer to each other

Copy code The code is as follows:

function test(){
var a={ };
var b={};
a.prop=b;
b.prop=a;
}

In this way, the reference times of a and b are both 2. Even after the test() execution is completed, both objects have left the environment. There is no problem under the mark and clear strategy. The ones that leave the environment will be cleared, but It does not work under the reference counting strategy, because the number of references of these two objects is still 2 and will not become 0, so the space occupied by them will not be cleared. If this function is called multiple times, there will continue to be no space. will be recycled, causing memory leaks.

In IE, although JavaScript objects are garbage collected through mark and clear, BOM and DOM objects are garbage collected through reference counting, which means that as long as BOM and DOM are involved, circular reference problems will occur. Looking at the above example, some students thought it was too weak. Who would do such boring things? In fact, are we just doing it?

Copy code The code is as follows:

window.onload=function outerFunction(){
var obj = document.getElementById("element");
         obj.onclick=function innerFunction(){};
    };

This code looks fine, but obj refers to document.getElementById("element"), and the onclick method of document.getElementById("element") will refer to variables in the external environment, which naturally includes obj. Yes Not very hidden.

Solution

The simplest way is to manually release the circular reference yourself, for example, the function just now can be done like this

Copy code The code is as follows:

window.onload=function outerFunction(){
var obj = document.getElementById ("element");

When is garbage collection triggered?

The garbage collector runs periodically. If a lot of memory is allocated, the recycling work will be very arduous. Determining the garbage collection interval becomes a question worth thinking about. IE6's garbage collection runs based on the amount of memory allocation. When there are 256 variables, 4096 objects, or 64k strings in the environment, the garbage collector will be triggered. It looks very scientific, and there is no need to press a paragraph. It's only called once every time, sometimes it's not necessary, wouldn't it be nice to call it on demand? But if there are so many variables in the environment and the script is so complex now, it is normal, then the result is that the garbage collector is always working, so the browser cannot play.

Microsoft has made adjustments in IE7. The trigger conditions are no longer fixed, but dynamically modified. The initial value is the same as IE6. If the memory allocation amount recovered by the garbage collector is less than 15% of the memory occupied by the program, it means Most of the memory cannot be recycled. The set trigger condition for garbage collection is too sensitive. At this time, double the street condition. If the recycled memory is higher than 85%, it means that most of the memory should be cleaned up long ago. At this time, set the trigger condition back. . This makes the garbage collection job a lot more functional. Similar to C# and Java, we can manually call the garbage collection program, but because it consumes a lot of resources, and what we call manually will not be more accurate than what the browser can judge, it is not recommended to call the garbage collection program manually.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn