What is a memory leak

When memory that is no longer needed by an application is for some reason not returned to the operating system or free memory, this can result in slow, stuttering, and high latency

Two. The main cause of memory leakage

The main cause of JavaScript memory leaks is a few Unwanted References.

Unwanted References refer to the memory that the developer no longer needs, but that for some reason is still marked and left in the active root tree. Unwanted References are the References for the memory. In the context of JavaScript, Unwanted References are variables that you no longer need that point to some memory that could have been released.

Common memory leaks

1. Memory leaks caused by global variables

In JS, global variables are referenced directly by the root node, so they are not recycled throughout the life of the program

  • Reference undeclared variables
function foo(arg) {
    bar = "this is a hidden global variable";
}
Copy the code
  • Set the variable to a property of the global variable Window
function foo(arg) {
    window.bar = "this is an explicit global variable";
}
Copy the code
  • Blind use of this causes mounting to properties of global variables
function foo() {
    this.variable = "potential accidental global";
}
foo();
Copy the code

In conclusion:

1. To avoid accidentally creating global variables, use strict mode.

2. Reduce the creation of global variables

3. If you must use global variables to store a large amount of data, you must ensure that the data is null or reassigned after processing

2. Forgetting to release the timer

3. Multiple references

When multiple variables refer to the same object, any reference that is not cleared will result in the referenced object being unable to be GC.

Example:

var elements = {
    button: document.getElementById('button'),
    image: document.getElementById('image'),
    text: document.getElementById('text')
};

function doStuff() {
    image.src = 'http://some.url/image';
    button.click();
    console.log(text.innerHTML);
    // Much more logic
}

function removeButton() {
    // The button is a direct child of body.
    document.body.removeChild(document.getElementById('button'));

    // At this point, we still have a reference to #button in the global
    // elements dictionary. In other words, the button element is still in
    // memory and cannot be collected by the GC.s
}
Copy the code

In the above code example, #button is referenced by two variables, one in the DOM tree and one in the Elements object. If you decide to reclaim a button in the future, you will need to release both references, and the code above only releases the button reference in the DOM, while the Element object still holds the reference to the button, so the button will not be GC

Another situation is that if we want to reclaim a table, but we keep a reference to a cell in the table, the entire table will be kept in memory and cannot be GC.

4. The closure

Closure: A Closure is a function that can access variables defined in its Enclosing Scope, even if the Enclosing Scope is over. Therefore, closures have the ability to remember the Context around them.

Example:

var newElem;
function outer() {
   var someText = new Array(1000000);
   var elem = newElem;
   function inner() {
       if (elem) return someText;
   }
   return function () {};
}
setInterval(function () {
   newElem = outer();
}, 5);
Copy the code

In this example, there are two closures: one is inner, and the other is the anonymous function function () {}. The inner closure refers to someText and elem, and inner is never called. However, we need to note that closures with the same parent scope can share the context. That is, in this example, inner’s someText and elem will be shared with the anonymous function function () {}. However, this anonymous function is then returned by return and assigned to newElem. As long as newElem references the anonymous function, then someText and ELEm are not GC.

Also, notice that var elem = newElem is executed inside outer; , and this newElem refers to the anonymous function returned from the last call to Outer. Imagine that the NTH call to outer holds the anonymous function from the NTH call to Outer. This anonymous function holds a reference to elem and, in turn, a reference to the NTH call to… Therefore, this will cause a memory leak.

Solution: change the code for parameter 1 in setInterval to newElem = outer()();

5.console.log

Since the objects we pass to console.log need to be printed out to the console to view information, the memory of these objects will not be garbage collected, which will also cause memory leaks.


Read the link:

Auth0.com/blog/four-t…