Principle of Js Recycling Mechanism

Posted by AsiaUnderworld on Sat, 25 Dec 2021 17:37:36 +0100

Existential Significance

JS's garbage collection mechanism is designed to prevent memory leaks. Memory leaks mean that a piece of memory exists when it is no longer needed. The garbage collection mechanism periodically finds variables that are no longer in use and releases the memory they point to.
In JS, the JS execution environment is responsible for managing the memory used during code execution.

Accessibility

The main concept of memory management in JavaScript is accessibility.

  1. There is a basic set of intrinsic reachable values that cannot be deleted for obvious reasons. For example:
  • Local variables and parameters for local functions
  • Variables and parameters of other functions on the current nested call chain
  • global variable
  • There are other, internal
  • These values are called roots.
  1. If a reference or reference chain can access any other value from the root, it is considered accessible.

For example, if there is an object in a local variable and the object has an attribute that refers to another object, the object is considered accessible, and those references are also accessible. Detailed examples are given below.

There is a background process in the JavaScript engine called the garbage collector that monitors all objects and deletes those that are inaccessible.

Interrelated Objects
function marry (man, woman) {
woman.husban = man;
man.wife = woman;

return {
father: man,
mother: woman
}
}

let family = marry({
name: "John"
}, {
name: "Ann"
})

Internal algorithm-reference counting

In a memory-managed environment, if Object A has access to Object B, it is called Object A refers to Object B. The strategy for reference counting is to simplify whether an object is no longer needed to be referred to by another object. If no object references this object, it will be recycled.

let obj1 = { a: 1 }; // An object (called A) is created and assigned to obj1, with a reference number of 1 
let obj2 = obj1; // The number of references to A becomes 2

obj1 = 0; // The number of references to A becomes 1
obj2 = 0; // The number of references to A becomes zero, and object A can be garbage collected.
But the biggest problem with reference counting is circular references.

function func() {
    let obj1 = {};
    let obj2 = {};

    obj1.a = obj2; // obj1 references obj2
    obj2.a = obj1; // obj2 references obj1
}
Two objects are created and referenced, creating a loop that leaves the scope of the function after being called.
So it's no longer useful and can be recycled, but it references each other, so it won't be recycled.

To solve the problem of circular references, it is best to manually leave them empty when you are not using them.
The example above can do this:
obj1 = null;
obj2 = null;

Internal algorithm-Tag-Clear algorithm

This algorithm simplifies the definition of "whether an object is garbage" to "whether an object is available or not". If it is not found, it will be recycled by the garbage collection mechanism.
There are two phases, marking and clearing
During the markup phase, the garbage collector traverses through the root object. Each object accessible from the root object is added with an identity, which identifies the object as reachable.
During the cleanup phase, the garbage collector linearly traverses the heap memory from beginning to end. If it finds that an object has not been identified as reachable, it reclaims the memory occupied by the object and clears the identity that was previously marked as reachable for the next garbage collection operation.


Clear all tags and perform the next operation (because memory changes dynamically)

It doesn't matter if there are two circular references, they can't be found from the root, they're not marked, and they'll be cleared later

Memory leak

Unexpected global variable

   
  function fn() {
    a = new Array(10000000)                            
    console.log(a)
  }
  fn()

When global variables are used to temporarily store and process large amounts of information, care needs to be taken. If you must use a global variable to store a large amount of data, be sure to set it to null Or redefine it.

Timer or callback function not cleaned up in time

  Timer or callback function not cleaned up in time
  var intervalId = setInterval(function () { //Do not clean up after starting cycle timer
    console.log('----')
  }, 1000)

  // clearInterval(intervalId)

closure

A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within one function and access its local variables through another function.

function assignHandler(){
  var element = document.getElementById("someElement");
  var id = element.id;
  element.onclick = function(){
      alert(id);
  };
  element = null;
}

Because closures cause variables in functions to be stored in memory and consume a lot of memory, they cannot be abused or they can cause performance problems for Web pages and memory leaks in IE. The solution is to delete all unused local variables before exiting the function.
This is because IE browsers used reference counting in the early days, and if circular references were formed between two objects, neither object could be recycled, but memory leaks caused by circular references were not essentially caused by closures.

Optimize to reduce recycling

1. object Object Optimization

To maximize object reuse, you should avoid using {} to create new objects just as you would avoid using a new statement. One way to ensure reuse of objects (to make sure there are no attributes on the object prototype) is to iterate through all the attributes of the object, delete them one by one, and eventually clean up the object as an empty object.

cr.wipe = function (obj) {
    for (var p in obj) {
         if (obj.hasOwnProperty(p))
            delete obj[p];
    }
};

You can reuse objects by using the cr.wipe(obj) method to clean them up and adding new attributes to obj. Although it may take more time to get a "new object" by emptying an object than simply creating it by {}, this short amount of time consumed in code with high real-time requirements will effectively reduce garbage heap and eventually avoid garbage collection pauses

2. Array array optimization

Shortcut to emptying the array: arr = [];This creates a new empty object and turns the original array object into a small piece of memory garbage!
arr.length = 0 It can also empty the array and reuse the array to reduce the generation of memory garbage.

3. Method function Optimization

function func() {
    return function() {};            //A new object is created each time a function is called:
}

Methods are typically created at initialization time, and thereafter very few dynamic memory allocations occur at runtime. Using these forms in setTimeout can cause problems.

Topics: Javascript