JavaScript garbage collection mechanism analysis

  • 2020-03-26 21:20:26
  • OfStack

In the company will often hear Daniel said discuss memory leaks or something, often have breath away, the recent energy is mainly used in the Web development, read the "JavaScript high-level programming" (the title is very complete, especially written by the author in practice and good 1) take a look at the JavaScript garbage collection mechanism, to 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 the management of the memory used in the code execution process, so there is no need to consider the memory allocation and garbage collection during the development process. The mechanism for JavaScript garbage collection is simple: find variables that are no longer in use and free up their memory, but this process is not constant because it is expensive, so the garbage collector periodically executes at regular intervals.

Variable life cycle

Some of you will look at it and say, what is a variable that is no longer used? Variables that are no longer in use are variables that end their life cycle, which can only be local variables, of course. The life cycle of global variables does not end until the browser unloads the page. Local variable in a function only exist in the implementation process, and in the process for local variables corresponding space allocated on the stack or heap, to store their values, and then use these variables in functions, until the end of the function (closure due to the reason of the internal function and external function is not end, understand closures can see JavaScript scope chain, what exactly is a JavaScript closures).

Once the function is over, local variables are no longer necessary and the memory they occupy can be freed. Why do cats and simple jobs cost so much? This is just the tip of the garbage collection iceberg, like the closure just mentioned, it looks like the function is over, but it's not, the garbage collector has to swim with that variable, that variable doesn't work, and tag variables that are no longer useful for future collection. There are a number of strategies for marking garbage, and two are common

Mark and sweep

This is the most common form of garbage collection in JavaScript. When a variable enters the execution environment, such as when a variable is declared in a function, the garbage collector marks it as "entering the environment" and when the variable leaves the environment (when the function is executed), it marks it as "leaving the environment." There are many ways to mark, such as special bit inversion, maintaining a list, and so on. It is not important that what strategy is used. In principle, it is impossible to free up the memory occupied by variables entering the environment, which may be called at any time.

Garbage collector will run when adding tags to all variables stored in the memory, and then remove the variables and the environment by environment variables referenced (closures), still exist after completion of these variables is to remove the tag, because the environment has been unable to access to the variables, then garbage collector meet these variables with a tag machine occupies space.

Most browsers use this method for garbage collection. The difference is how to mark and garbage collection interval.

Reference counting

Memory leaks are common in low versions of IE, often because of its use of reference counting for garbage collection. Reference counting strategy is to track the number of each value is used, when declaring a variable and will be a reference type assigned to the variable when the value of the reference number is, if it is the value of a variable into another, this is worth reference number minus 1, when the value of citations to 0, show that no variables in use, this value can not be visited, so it can be to take up the space is recycling, garbage collector will be at run time to clear off the value of the citations of 0 to take up space.

It seems like a good way to do it. Why are so few browsers using it, and why does it cause memory leaks? Mainly because it doesn't solve the circular reference problem. So for example, object A has A property that points to object B, and object B has A property that points to object A, so they refer to each other

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

Such citations of a and b is 2, even if in the test (), after the completion of two objects have to leave the environment, there is no question of under the strategy of tag removal, leave the environment will be cleared, but not under the reference counting strategy, because the two object reference number is still 2, will not be 0, so its take up the space is not clear, if the function is called many times, so that it will continue to have space won't be recycled, cause memory leaks.

In IE, although JavaScript objects are garbage collected by means of tag cleaning, BOM and DOM objects are garbage collected by reference counting, that is to say, as long as BOM and DOM are involved, circular reference problems will occur. Look at the above example, some students think it is too weak, who will do such a boring thing, in fact, we are not doing

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 ") refers to a variable in the external environment, including obj.

The solution

The easiest way to do this is to manually unloop the reference yourself, as in the previous function

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

When does garbage collection trigger

The garbage collector runs periodically, and if there is a lot of memory allocated, the garbage collection can be difficult, and determining the garbage collection interval becomes a question worth thinking about. IE6 garbage collection is run according to the memory allocation, when there are 256 variables, 4096 objects, 64k string any one of the conditions will trigger the garbage collector to work, it seems very scientific, not by a period of time to call once, sometimes not necessary, so call on demand is not good? But if the environment just has so many variables and so on all the time, and the script is so complicated that it's normal, then the result is that the garbage collector is working all the time, and the browser can't play with it.

Microsoft made adjustment in IE7, the trigger condition is no longer a fixed, but the dynamic modification, the initial value is the same as the IE6, if the garbage collector memory allocation amount less than 15% of the program memory, that most of the memory cannot be recycled, and the recycling trigger condition is too sensitive, this time the double street condition, if the memory of recycling is greater than 85%, that should have been cleaned up most of the memory, then put the trigger condition. This makes garbage collection a lot more functional.

Just like C# and Java, we can call the garbage collector manually, but because it consumes a lot of resources, and our manual call is not more accurate than the browser's judgment, it is not recommended to call the garbage collector manually.

Related articles: