js garbage collection and memory leak

js garbage collection

The Javascript of the browser has an automatic garbage collection mechanism (GC). The garbage collector will periodically (periodically) find out those variables that are no longer in use, and then release their memory. However, this process is not real-time, because it is expensive and stops responding to other operations during GC, so the garbage collector will execute periodically at fixed time intervals.
How to identify which variables can be recycled?

The garbage collector must track which variables are useless and mark variables that are no longer useful for future memory recovery. There are usually two implementations: tag cleanup and reference counting. Reference counting is less commonly used, and mark clearing is more commonly used.

Mark clear

The most common garbage collection method in js is tag cleanup. When a variable enters the environment, such as declaring a variable in a function, the variable is marked as "entering the environment". Logically, the memory occupied by variables entering the environment can never be released, because they may be used as long as the execution flow enters the corresponding environment. When a variable leaves the environment, it is marked as "leaving the environment".

function fn(){
var a = 10 ;       // Marked to enter the environment 
var b = 20 ;       // Marked to enter the environment
}
fn();            // After execution, a and b are marked out of the environment and recycled.

So far, the JS implementations of IE9 +, Firefox, Opera, Chrome and Safari all use the garbage collection strategy of mark removal, but the garbage collection intervals are different from each other.

Reference count

The meaning of reference count is to track the number of times each value is referenced. When a variable is declared and a reference type value is assigned to the variable, the number of references to this value is 1. If the same value is assigned to another variable, the number of references to the value is increased by 1. Conversely, if the variable containing the reference to this value gets another value, the number of references to this value is reduced by 1. When the number of references of this value becomes 0, it means that there is no way to access this value again, so the memory space occupied by it can be reclaimed. In this way, when the garbage collector runs again the next time, it will free up the memory occupied by values with 0 references.

function fn() {
    var a = {};    // a refers to the object 1 times
    var b = a;     // a the number of references to the object plus 1 is 2
    var c = a;     // a the number of references to the object plus 1 is 3
    var b = {};    // a the number of references to the object is reduced by 1 to 2
}

Memory leak

For continuously running service processes, the memory that is no longer used must be released in time. Otherwise, the memory will occupy more and more, which will cause memory leakage.

Memory leak in vue

  • If JS is used in the mounted/created hook to bind events in DOM/BOM objects, corresponding unbinding processing needs to be done in beforeDestroy;
  • If the third-party library initialization is used in the mounted/created hook, it needs to be destroyed in beforeDestroy (generally not used, because it is often directly global Vue.use);
  • If setInterval is used in the component, it needs to be destroyed in beforeDestroy;
// For example:
  mounted() {
    this.ele = document.querySelector('.home')
    // Add scroll listening event
    this.ele.addEventListener('scroll',this.handlerscroll)
  },
  // Remove listening events when a page is destroyed
  destroyed(){
	this.ele.removeEventListener('scroll',this.handlerscroll)
  }

Memory leak in js

1. Unexpected global variable

function fn() {
	a = 1
}
fn()
solve: window.a = null
 Or: in js Add at the beginning of file 'use strict',Turn on strict mode.

When fn is executed, because the internal variable is not defined, it is equivalent to window A = 1, after the function is executed, the variable a that should have been destroyed is permanently retained in memory.
Another

function fn(){
	this.a = 1	// this points to window
}
fn()
solve: window.a = null

2. Closure

When a variable outside a closure is introduced into a closure, the object cannot be garbage collected (GC) when the closure ends.

    function fn() {
        var a = 2
        function fn2() {
            console.log(++a);
        }
        return f2
    }
    var f = fn()
    f() 
    solve:f = null

3. DOM leakage

When the original parent node dom is removed, the child node is referenced and the parent node cannot be removed

var body = document.querySelector('body')
var father = document.querySelector('.father')
var son = document.querySelector('.son')
father.appendChild(son)
body.removeChild(father);
solve: father = null

4. The timer did not close in time

Only when the timer stops will it be recycled

setInterval((function(){
	console.log(1)
}, 1000)
Solution: call when not needed clearInterval

Keywords: Javascript Firefox safari

Added by maniac1aw on Fri, 21 Jan 2022 08:42:14 +0200