Mecanismo de recolección de basura JS y pérdida de memoria

1. Pérdida de memoria del navegador

El motor V8 encapsulado por el navegador admite el análisis de JS. Cuando el programa está en ejecución (tiempo de ejecución), siempre que el programa requiera memoria, como cuando se declaran variables como cadenas asignadas, objetos y matrices, el sistema operativo debe asignar memoria para su uso. Las variables del proceso del servicio en ejecución aumentan constantemente y la memoria no se libera a tiempo, la ocupación de la memoria aumentará cada vez más, lo que afectará el rendimiento del sistema o provocará directamente que el sistema se bloquee.

1. Cierre y referencia

    let fn = () =>{
    
    
        let a = 0
        return () => {
    
    
            return a++
        }
    }

    let b = fn()
    console.log(b())    // 0
    console.log(b())    // 1

Los cierres pueden provocar pérdidas de memoria en IE6, pero ya no se consideran. Aunque la variable a no se puede reciclar (equivalente a una variable global), no hay ninguna consideración especial para esta memoria. Vale la pena señalar que el cierre en sí mismo no causa pérdidas de memoria, pero demasiados cierres pueden conducir fácilmente a pérdidas de memoria.

2. Referencias mutuas

let aa = {
    
    }
let bb = {
    
    }
aa.c = bb
bb.c = aa

Solución: no se refiera a variables

3. Variables globales no declaradas

    function fn1() {
    
    
        aa = 1  //  window.aa
        console.log(aa)
    }
    fn2()

    function fn2() {
    
    
        this.bb = 1 //  window.bb
        console.log(bb)
    }
    fn2()

Las funciones fn1 y fn2 no se declaran, es decir, las variables están vinculadas a la ventana del objeto global, por lo que la memoria de variables no se puede liberar después de que se ejecuta la función.
Solución: use el modo estricto y agregue 'usar estricto' al principio de js

4. Función de temporizador y devolución de llamada

    let a = 2
    setInterval(() =>{
    
    
        console.log(a++)
    }, 1000)

Cuando no se necesita setInterval o setTimeout, el temporizador no se borra y la función de devolución de llamada del temporizador y las variables dependientes internas no se pueden reciclar, lo que provoca pérdidas de memoria.

5. Agregue atributos al objeto DOM

document.getElementById('id')[property] = obj

Si el DOM existe, siempre vinculará este evento. La solución es la siguiente:

window.onunload = function(){
    
    
  document.getElementById('id')[property] = null
}

7. Temporizadores, monitoreo de eventos, $ on, etc. en vue.
Solución: elimine o cierre eventos relacionados en el gancho beforeDestroy

Dos, mecanismo de recolección de basura

Ciclo de vida de la variable: cuando finaliza el ciclo de vida de una variable, se debe liberar la memoria a la que apunta. JS tiene dos tipos de variables, variables globales y variables locales generadas en funciones (sin incluir las variables referenciadas). El ciclo de vida de una variable local finaliza después de que se ejecuta la función, y la memoria a la que hace referencia se puede liberar (es decir, recolectar basura), pero el ciclo de vida de una variable global continuará hasta que el navegador cierre la página. El recolector de basura detectará las variables que ya no están en uso, y luego liberará la memoria ocupada por ellas y las ejecutará periódicamente en un intervalo de tiempo fijo.

Hay dos tipos principales de mecanismos de recolección de basura en los navegadores modernos: eliminación de marcas y recuento de referencias.
1. Marcar y barrer Los
navegadores principales actuales de IE, Firefox, Opera, Chrome y Safari utilizan la estrategia de recogida de basura de marcar y barrer .
Cómo funciona: Cuando una variable ingresa al entorno, la variable se marca como "ingresar al entorno". Cuando una variable abandona el entorno, se marca como "fuera del entorno". Se recupera la memoria marcada "Dejar el medio ambiente".

Flujo de trabajo:
1. El recolector de basura marcará todas las variables almacenadas en la memoria cuando se esté ejecutando.
2. Elimine las variables globales y las etiquetas de las variables referenciadas por las variables en el entorno.
3. La marcada se considerará como la variable a eliminar.
4. El recolector de basura completa la limpieza de la memoria, destruye los valores marcados y recupera el espacio de memoria que ocupan.

2. Recuento de referencias (recuento de referencias)
El significado del recuento de referencias es rastrear y registrar el número de veces que se hace referencia a cada valor. Cuando se declara una variable y se asigna un valor de tipo de referencia a la variable, el número de referencias a este valor es 1. Si se asigna el mismo valor a otra variable, el número de referencias al valor se incrementa en 1. Por el contrario, si la variable que contiene una referencia a este valor obtiene otro valor, el número de referencias a este valor se reduce en 1. Cuando el número de referencias a este valor es 0, significa que ya no hay forma de acceder a este valor, por lo que puede Recupere el espacio de memoria que ocupaba.

let aa = []   // 数组[]引用1次
let bb = aa  //  数组引用2次
bb = null  //  释放内存,引用还剩下1次,即变量aa的引用还存在

Un mecanismo de recolección de basura tan simple es muy propenso a problemas de referencia circular, que pueden hacer que la memoria no se recicle y provocar pérdidas de memoria; por ejemplo:
let aa = {}
let bb = {}
aa.c = bb
bb.c = aa

var wraper = document.querySelector('#btn');
wraper.onclick = handle;
wraper = null;

wraper = null;
Este método no puede liberar el evento dom click, porque la variable a la que hace referencia el wrapper se libera. El objeto real DOM ya ha vinculado el evento btn click, por ejemplo

  let a = {
    
    }
    let b = a
    b.btn = () =>{
    
    }
    b = null
    console.log(a)

Supongo que te gusta

Origin blog.csdn.net/zxlong020/article/details/108566610
Recomendado
Clasificación