Introduction
Low-level languages, such as C, have low-level memory management primitives, such as malloc() and free(). JavaScript's memory primitives, on the other hand, are allocated when variables (objects, strings, etc.) are created and then "automatically" freed when they are no longer used. The latter is called garbage collection. This "automatic" is confusing and gives JavaScript (and other high-level language) developers the illusion that they don't have to think about memory management.
Memory life cycle
No matter what programming language, the memory life cycle is basically the same:
1. Allocate the memory you need
2. Use it (read, write)
3. Release it when it is not used ps: It has the same meaning as "putting an elephant in the refrigerator"
The first and second parts of the process are clear in all languages. The last step is clear in low-level languages, but in high-level languages like JavaScript, the last step is not clear.
JavaScript memory allocation
Variable initialization
In order to not make programmers worry about allocation, JavaScript completes the memory allocation when defining variables.
var o = {
a: 1,
b: null
}; // Allocate memory for the object and its containing variables
var a = [1, null, "abra"]; // Allocate memory for the array and its containing variables (just like objects)
function f(a){
return a 2;
} // Allocate memory for the function (callable object)
// Function expressions can also allocate an object
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false);
Memory allocation via function call
Some function calls result in object memory allocation:
Some methods allocate new variables or new objects:
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // There are four elements in the new array that connect array a and array a2.
Use of values
The process of using values is actually an operation of reading and writing allocated memory, which means that you can write a variable or an object's attribute value, and even pass function parameters.
Release memory when it is no longer needed
Most memory management problems occur at this stage. The most difficult task here is to find that the allocated memory is indeed no longer needed. It often requires the developer to determine which piece of memory in the program is no longer needed and free it.
The high-level language interpreter embeds a "garbage collector" whose main job is to track the allocation and use of memory so that it can be automatically released when the allocated memory is no longer used. This process is an approximation, because knowing whether a certain piece of memory is needed is undecidable (cannot be solved by a certain algorithm).
Garbage Collection
As mentioned above, the problem of automatically finding whether some memory is "no longer needed" cannot be determined. Therefore, garbage collection implementations can only solve general problems to a limited extent. This section explains the concepts necessary to understand the main garbage collection algorithms and their limitations.
Quote
Garbage collection algorithms mainly rely on the concept of references. In the context of memory management, if an object has permission to access another object (implicitly or explicitly), it is called an object referencing another object. For example, a Javascript object has a reference to its prototype (an implicit reference) and a reference to its properties (an explicit reference).
Here, the concept of "object" is not only a special Javascript object, but also includes function scope (or global lexical scope).
Reference counting garbage collection
This is the simplest garbage collection algorithm. This algorithm simplifies the definition of "whether the object is no longer needed" as "whether the object has other objects referencing it." If there are no references pointing to the object (zero references), the object will be reclaimed by the garbage collection mechanism.
For example
var o2 = o; // The o2 variable is the second reference to "this object"
o = 1; // Now, the original reference o of "this object" is replaced by o2
var oa = o2.a; // Reference the a property of "this object"
// Now, "this object" has two references, one is o2 and the other is oa
o2 = "yo"; // The original object now has zero references
// He can be garbage collected
// However, the object of its attribute a is still referenced by oa, so it cannot be recycled yet
oa = null; // The object with the a attribute now also has zero reference
// It can be garbage collected
Limitation: circular reference
A limitation of this simple algorithm is that if one object references another (forming a circular reference), they may be "no longer needed", but they will not be recycled.
return "azerty";
}
f();
// Two objects are created and reference each other, forming a loop
// They will not leave the function scope after being called
// So they are no longer useful and can be recycled
// However, the reference counting algorithm takes into account that they all have at least one reference to each other, so they will not be recycled
Practical examples
IE 6, 7 performs reference counting recycling on DOM objects. A common problem for them is memory leaks:
Mark-and-clear algorithm
This algorithm simplifies the definition of "whether the object is no longer needed" as "whether the object can be obtained."
This algorithm assumes setting up an object called root (in Javascript, root is the global object). Periodically, the garbage collector will start at the root, find all objects referenced from the root, and then find the objects referenced by these objects... Starting from the root, the garbage collector will find all objects that can be obtained and all objects that cannot be obtained.
This algorithm is better than the previous one, because "object with zero reference" is always unobtainable, but the opposite is not necessarily true, refer to "cyclic reference".
As of 2012, all modern browsers use the mark-and-sweep garbage collection algorithm. All improvements to the JavaScript garbage collection algorithm are based on improvements to the mark-sweep algorithm, and do not improve the mark-sweep algorithm itself and its simplified definition of "whether an object is no longer needed."
Circular references are no longer a problem
In the above example, after the function call returns, the two objects cannot be obtained from the global object. Therefore, they will be collected by the garbage collector.
In the second example, once the div and its event handlers are unreachable from the root, they will be collected by the garbage collector.
Limitations: Objects need to be explicitly unreachable
Although this is a limitation, it is rarely exceeded, which is why in reality few people care about the garbage collection mechanism.