Introduction
Low-level languages, such as C, have low-level memory management commands, such as malloc() and free(), which require developers to release memory manually. However, the situation in high-level languages such as JavaScript is different. Objects (objects, strings, etc.) allocate memory when they are created. When they are no longer in use, the memory will be automatically recycled. This automatic recycling process is called garbage collection. Because of the existence of garbage collection, developers of high-level languages such as JavaScript have a wrong understanding, thinking that they don't need to care about memory management.
Memory life cycle
Regardless of the programming language, the memory life cycle is basically the same.
1. Allocate the memory you need
2. Use it for read and write operations
3. Release resources when the memory is no longer needed
Steps 1 and 2 are the same for all languages. Clearly aware. As for step 3, low-level languages require developers to perform this explicitly. For high-level languages like JavaScript, this part of the operation is done by the parser, so you won't notice it.
Allocation operation in JavaScript
Initialization of value
When assigning a value to a variable, JavaScript will complete the memory allocation.
var n = 123; // Allocate memory for numbers
var s = "azerty"; // Allocate memory for string
var o = {
a: 1,
b: null
}; // For object containing attribute values Allocate memory
var a = [1, null, "abra"]; // Allocate memory for the array containing the value
function f(a){
return a 2;
} // for Functions allocate memory (functions are callable objects)
// Function expressions are also objects, and there is a case of allocating memory
someElement.addEventListener('click', function(){
someElement.style. backgroundColor = 'blue';
}, false);
Allocation is completed through function calls
After some functions are executed, object allocation also occurs.
var d = new Date();
var e = document.createElement('div'); // Allocate a DOM element
Some methods allocate new values or objects.
var s = "azerty";
var s2 = s.substr(0, 3); // s2 is a new string
// Since the string is unchanged, javascript will create a new string for the content in the range [0, 3]
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // put a and a2 are combined to produce a new array
Use of values
Using values is actually to perform read and write operations on allocated memory. These operations include: reading and writing operations on variables or object properties, or passing parameters to functions.
Release memory when it is no longer needed
Most memory management problems occur at this stage. The hardest thing to do is how to determine when the allocated memory is no longer needed. This often requires developers to determine when the program no longer needs memory and release the resources it occupies.
A program called the "garbage collector" is embedded in the high-level language parser. His job is to track the allocation and use of memory, determine whether the memory is needed, and perform resource release operations when it is no longer needed. . He can only obtain an approximation, because determining whether a memory is needed is an uncertain problem (cannot be solved by an algorithm).
Garbage collection
As mentioned above, we cannot accurately and automatically determine that "memory is no longer needed". Therefore, garbage collection has limitations as a solution to this problem. This section explains the concepts necessary to understand the major garbage collection algorithms and their limitations.
Reference
One of the main concepts in garbage collection is reference. In memory management, when an object uses another object, whether explicitly or implicitly, we say that it refers to another object. For example, a JavaScript object has an implicit reference to its prototype and explicit references to its property values.
Here, the concept of object goes beyond the traditional concept of object in JavaScript. It also includes function scope and global scope.
Garbage collection using reference counting algorithm
What is introduced below is an optimal algorithm, which introduces the concepts of "the object is no longer needed" and "no other objects refer to the object". When the object's reference pointer becomes 0, it is considered ready for recycling.
Example:
var o = {
a: {
b:2
}
}; // Two objects are created. One object (a) is referenced by another object (the object referenced by o), and uses a as its attribute
// The object is referenced by the variable o again
// Obviously, no object can be recycled at this time
var o2 = o; // The variable o2 refers to the object again
o = 1 ; // o no longer refers to the object, only o2 still refers to the object
var oa = o2.a; // oa refers to o2's attribute object a
// This object is referenced by two other objects, They are the attribute a and oa variable of o2 respectively
o2 = "yo"; // This object is no longer referenced by other objects, but its attribute a is still referenced by the oa variable, so it cannot be released yet
oa = null; // Now attribute a is no longer referenced by other objects, and the object can be recycled
Limitations: Loops
This algorithm has its limitations, when a When an object refers to another object, a circular reference is formed, and the garbage collector will not reclaim them even if they are no longer needed.
function f(){
var o = { };
var o2 = {};
o.a = o2; // o refers to o2
o2.a = o; // o2 refers to o
return "azerty";
}
f();
// Two objects are created and form references to each other
// After the function call ends, they will not leave the function scope. Although they will not be used, they will not be Release
// This is because the reference counting algorithm determines that as long as the object is referenced, garbage collection cannot be performed on it
Real-life examples
ie6, 7 , using the reference counting algorithm on the DOM object, there will be a memory leak problem.
var div = document.createElement("div");
div.onclick = function(){
doSomething();
}; // div refers to the event handler through the click attribute
// When the div variable is accessed in the event handler function , will form a circular reference, which will cause both objects to not be recycled, causing memory leaks
Mark-Sweep Algorithm
He introduces the concepts of "object no longer needed" and "object inaccessible (object unreachable)". This algorithm assumes that there is a series of root objects (the root object in JavaScript is the global object). Every once in a while, the garbage collector will start from the root object, traverse all the objects it references, and then traverse the objects referenced by the reference object. And so on. Using this approach, the garbage collector can obtain all accessible objects and reclaim those that are inaccessible.
This algorithm is better than the previous algorithm. Objects referenced by 0 will be set as inaccessible objects. At the same time, it also avoids the trouble caused by circular references.
As of 2012, most modern browsers use this "mark-and-sweep" garbage collector. The field of JavaScript garbage collection (generational/incremental/concurrent/parallel garbage collection) has improved the algorithms related to it in the past few years, but the garbage collection algorithm itself (mark-sweep algorithm) and "how to determine whether an object is no longer need" has not been improved.
Periodicity is no longer a problem
In the first example, after the function call ends, these two objects will not be referenced by the global object, nor will they be referenced by the object referenced by the global object. Therefore, they will be marked as inaccessible objects by the JavaScript garbage collector. The same thing happens in the second example, when the div and event handler are marked as inaccessible by the garbage collector, they will be released.
Limitations: Objects need to be explicitly marked as inaccessible
This marking method has limitations, but we are not exposed to it in programming, so we rarely care about garbage collection related content.