Today we will summarize the JS garbage collection mechanism. This paper mainly describes the definition of GARBAGE in JS, garbage recovery algorithm, shortcomings and improvement methods.
What is garbage
What we do not use in our daily life can be called “garbage”. But in JS, garbage more often refers to things that are not needed (variables, objects, etc.). To judge whether a variable is garbage, I summarize the following points:
- All global variables, window (or global) objects are not garbage
- All variables have a life cycle, and local variables become garbage when they exit their scope
For local variables, they can be divided into the following three situations:
- Single reference
var a = {
name: 'frank'
}
Copy the code
- Double quotes
var a= {
name: "frank";
}
var admin = a
Copy the code
If you eliminate the a variable, but there are still variables that reference it, then it won’t be garbage
- Ring reference
function marry(man, woman){
woman.husband = man;
man.wife = woman;
return {
father: man,
mother: woman
}
}
let family = marry({
name: "John"
},{
name: "Ann"
})
Copy the code
Then the global variable family is referenced by father John and mother Ann respectively, and man and woman are referenced by wife and husband to form a ring.
So if you delete father and husband, father won’t be garbage, because father will be garbage, even if the wife reference is still there, but it doesn’t reference anyone else.
All references to it need to be deleted
If the window does not point to the family, even though the family and father and wife refer to each other, the entire ring becomes garbage
Garbage collection algorithm
Here is a brief introduction to the principles of several common JS garbage collection algorithms, without showing the source code
- Mark -swipe algorithm
Start with “global” to find each arrow, mark the arrow that is used by someone, cannot delete, then go through each marked object, check all, find no new object, then look at the arrow that is not marked, delete all
A significant disadvantage of this algorithm is that when there are many objects, garbage collection is significantly slower due to the single-threaded JS, and it breaks if there is additional JS code that needs to be executed during execution.
So how can it be improved?
- The method of generation collection can be adopted, which divides the marked objects into the new generation and the old generation and recycles them by generation
- Incremental collection, in chronological order, checks a batch of variables, executes JS code for a period of time, and then checks again
- Collect it at idle time and wait until you no longer need to execute the JS code
But for the front end, there’s also the DOM process:
var div = document.getElementById('xxx'); Div. Onclick = function(){} // functions should not be treated as garbage setTimeout(function(){div.remove() // only removed from the page, But the memory also}, 3000) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - var div = document. GetElementById (' XXX '); Div. Onclick = function(){} // Functions should not be treated as garbage. SetTimeout (function(){div = null) But the div inside the HTML is still in the page! }, 3000).Copy the code
For the above code, making div equal to null removes the onclick function, otherwise it cannot be reclaimed
However, IE has a bug, which assumes that the DOM will not be referenced when the onclick function exists, so the DOM cannot be retrieved even if the onclick function exists first and then null
- Reference Counting algorithm
-
count
-
For example, if all global variables are labeled as 1 and you generate a new object, you add 1 if you reference it once, and -1 if you don’t
-
As long as the variable is not zero, no collection is done
-
Recycle when the count is 0
This algorithm does not require scanning and can immediately reclaim variables, but it also has disadvantages:
The processing of the multiplicator is heavy, and there is no way to count for circular references
- Mark compression algorithm
This algorithm uses the heap for token compression, which is not explained here due to its complexity. If you are interested, take a look at the following diagram: