Introduction to JavaScript memory management

  • 2020-05-12 02:16:37
  • OfStack

Introduction to the

Low-level languages, such as C, have low-level memory management primitives, like malloc(),free(). On the other hand, the memory primitives of JavaScript are allocated when variables (objects, strings, and so on) are created and then "automatically" released when they are no longer in use. The latter is called garbage collection. This "automation" is confusing and gives JavaScript (and other high-level languages) developers the illusion that they can ignore memory management.

Memory life cycle

Regardless of the programming language, the memory life cycle is basically 1 to:

1. Allocate the memory you need
2. Use it (read, write)
3. Release ps when it's not in use: same as "refrigerate an elephant.

The part 12 process is clear in all languages. The last step is clear in low-level languages, but not in high-level languages like JavaScript.

Memory allocation for JavaScript

Variable initialization

To keep programmers from bothering with allocation, JavaScript allocates memory when it defines variables.


var n = 123; // Allocate memory to numeric variables
var s = "azerty"; // To the character var o = {
  a: 1,
  b: null
}; // Allocates memory for objects and their containing variables var a = [1, null, "abra"]; // Allocates memory for arrays and their containing variables (just like objects)
function f(a){
  return a + 2;
} // Allocates memory for functions (callable objects) // Functional expressions can also be assigned 1 An object
someElement.addEventListener('click', function(){
  someElement.style.backgroundColor = 'blue';
}, false);

Memory allocation via function calls

Some function calls result in allocating object memory:


var d = new Date();
var e = document.createElement('div'); // distribution 1 a DOM The element

Some methods assign new variables or objects:


var s = "azerty";
var s2 = s.substr(0, 3); // s2 is a new string
// because string It's the invariant, JavaScript Maybe no memory is allocated, but it's just stored 0-3 The scope of. var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // The new array has a concatenation array a And an array a2 In the 4 An element.

The use of the value

The process of using a value is actually a read and write operation on the allocated memory, which means that it is possible to write the property value of a variable or an object, or even pass the parameters of a function.

Freed when memory is no longer needed

Most memory management issues are at this stage. The hardest task here is to find out "the allocated memory is really no longer needed." It often requires the developer to determine which chunk of memory in the program is no longer needed and to free it.

The high-level language interpreter is embedded with a "garbage collector," which tracks the allocation and use of memory so that when allocated memory is no longer used, it is automatically freed. This process is approximate because it is impossible to know whether a block of memory is needed or not (it cannot be solved by an algorithm).

The garbage collection

The problem of automatically finding whether some memory is "no longer needed" as described above cannot be determined. Therefore, garbage collection implementation can only be limited to solve the problem of 1. This section explains the concepts necessary to understand the major garbage collection algorithms and their limitations.

reference

Garbage collection algorithms rely heavily on the concept of references. In a memory-managed environment, an object that has access (implicitly or explicitly) to another object is called an object that references another object. For example, an Javascript object has a reference to its stereotype (an implicit reference) and a reference to its properties (an explicit reference).

Here, the concept of "object" is not only specific to Javascript objects, but also includes the function scope (or global lexical scope).

Reference count garbage collection

This is the simplest garbage collection algorithm. This algorithm simplifies the definition of "whether the object is no longer needed" to "whether the object has other objects to refer to it". If there is no reference to the object (zero reference), the object is collected by the garbage collection mechanism.

For example,


var o = {
  a: {
    b:2
  }
};
// Two objects are created, 1 As the other 1 The properties of two are referenced 1 One is assigned to a variable o
// Apparently, no 1 One can be garbage collected var o2 = o; // o2 A variable is the first 2 A reference to "this object"
o = 1; // Now, the original reference to "this object. o be o2 To replace the var oa = o2.a; // Reference "this object" a attribute
// Now, "this object" has two references, 1 One is o2 . 1 One is oa o2 = "yo"; // The original object is now zero-referenced
// He can be garbage collected
// But its properties a The object is still being oa Reference, so it cannot be recycled yet oa = null; // a The object of the property is now also zero-referenced
// It can be garbage collected

Limitation: circular reference

One limitation of this simple algorithm is that if one object references another (creating a circular reference), they may "no longer be needed," but they will not be recycled.


function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o reference o2
  o2.a = o; // o2 reference o   return "azerty";
} f();
// Two objects are created, referenced to each other, and formed 1 A loop
// They don't leave the scope of the function once they're called
// So they are no longer used and can be recycled
// However, the reference counting algorithm takes into account that they all have at least one another 1 Secondary references, so they won't be recycled

A practical example

IE 6, 7 does reference count collection on DOM objects. For them, a common problem is memory leaks:


var div = document.createElement("div");
div.onclick = function(){
  doSomething();
};
// div There are the 1 Two references point to the event handling property onclick
// Event handling is also available 1 A for div Can be accessed in the function scope
// This circular reference causes neither object to be garbage collected

Mark-sweep algorithm

This algorithm simplifies the definition of "whether the object is no longer needed" to "whether the object is available".

This algorithm assumes the setting of an object called root (in Javascript, the root is a global object). Periodically, the garbage collector will start at the root, find all the objects referenced from the root, and then find the objects referenced by those objects... Starting at the root, the garbage collector finds all available and all unavailable objects.

This algorithm is better than the previous one because "objects with zero references" are always not available, but instead are not fixed, referring to "circular references".

Since 2012, all modern browsers have used a mark-and-clear garbage collection algorithm. All the improvements to the JavaScript garbage collection algorithm are based on improvements to the mark-sweep algorithm, not to the mark-sweep algorithm itself and its simplified definition of "is the object no longer needed?"

Circular references are no longer an issue

In the example above, after the function call returns, the two objects cannot be retrieved from the global object. Therefore, they will be collected by the garbage collector.
The second example also shows that 1 div and its event handling cannot be fetched from the root, they will be collected by the garbage collector.

Limitation: objects need to be explicitly unavailable

Although this is a limitation, it is rarely breached, which is why few people care about garbage collection in reality.


Related articles: