Introducción
Los idiomas de bajo nivel, como C, tienen primitivas de gestión de memoria de bajo nivel, como Malloc () y Free (). Las primitivas de memoria de JavaScript, por otro lado, se asignan cuando se crean variables (objetos, cadenas, etc.) y luego se liberan "automáticamente" cuando ya no están en uso. Este último se llama recolección de basura. Esta "automática" está ofuscando y dando a los desarrolladores de JavaScript (y otros idiomas de alto nivel) una ilusión: pueden ignorar la gestión de la memoria.
Ciclo de vida de la memoria
No importa qué lenguaje de programación, el ciclo de vida de la memoria es básicamente el mismo:
1. Asignar la memoria que necesita
2. Úselo (lea, escriba)
3. Libere PS: y "Pon el elefante en el refrigerador" significa lo mismo
Las primeras y segundas partes del proceso son claras en todos los idiomas. El último paso es claro en idiomas de bajo nivel, pero en idiomas de alto nivel como JavaScript, el último paso no está claro.
Asignación de memoria para JavaScript
Inicialización variable
Para no molestar a los programadores con el problema de la asignación, JavaScript completa la asignación de memoria al definir variables.
La copia del código es la siguiente:
var n = 123;
var s = "Azerty";
var o = {
A: 1,
B: nulo
}; / / Asignar memoria para objetos y sus variables contenidas
var a = [1, nulo, "sujetador"];
función f (a) {
devolver a + 2;
} // Asignar memoria para funciones (objetos llamables)
// Las expresiones de funciones también pueden asignar un objeto
SomeEllement.AdDeventListener ('Click', function () {
SomeEllement.Style.BackgroundColor = 'Blue';
}, FALSO);
Asignación de memoria a través de llamadas de funciones
Algunas llamadas de función dan como resultado la asignación de la memoria del objeto:
La copia del código es la siguiente:
var d = nueva fecha ();
var e = document.createElement ('div');
Algunos métodos asignan nuevas variables o nuevos objetos:
La copia del código es la siguiente:
var s = "Azerty";
var s2 = s.substr (0, 3);
// porque la cadena es un invariante, JavaScript puede no asignar memoria, pero solo almacena el rango 0-3.
var a = ["ouais ouais", "nan nan"];
var a2 = ["generación", "nan nan"];
var a3 = A.concat (a2);
Uso de valores
El proceso de uso de valores es en realidad una operación de lectura y escritura de la memoria de asignación, lo que significa que se puede escribir una variable o el valor de la propiedad de un objeto, o incluso se pueden aprobar los parámetros de una función.
Liberado cuando la memoria ya no es necesaria
La mayoría de los problemas de gestión de la memoria están en esta etapa. La tarea más difícil aquí es encontrar "la memoria asignada ya no es necesaria". A menudo requiere que los desarrolladores determinen qué pieza de memoria en el programa ya no se necesita y la liberan.
El intérprete de lenguaje de alto nivel está integrado con un "recolector de basura" y su trabajo principal es rastrear la asignación y el uso de la memoria para que se libere automáticamente cuando la memoria asignada ya no esté en uso. Este proceso es una aproximación porque es imposible determinar si se debe determinar una determinada pieza de memoria (no se puede resolver por algún algoritmo).
Reciclaje de basura
Como se mencionó anteriormente, es imposible determinar la cuestión de buscar automáticamente si algo de memoria "ya no es necesario". Por lo tanto, la implementación de la recolección de basura solo puede resolver problemas generales con limitaciones. Esta sección explicará los conceptos necesarios para comprender los principales algoritmos de recolección de basura y sus limitaciones.
Cita
Los algoritmos de recolección de basura dependen principalmente del concepto de referencia. En un entorno administrado por la memoria, si un objeto tiene permiso para acceder a otro objeto (implícita o explícitamente), se llama un objeto que se refiere a otro objeto. Por ejemplo, un objeto JavaScript tiene una referencia a su prototipo (referencia implícita) y una referencia a sus propiedades (referencia explícita).
Aquí, el concepto de "objeto" no solo objetos especiales de JavaScript, sino también el alcance de funciones (o alcance léxico global).
Recolección de basura de conteo de referencia
Este es el algoritmo de recolección de basura más fácil. Este algoritmo simplifica "si el objeto ya no es necesario" como "si el objeto tiene otros objetos referenciados a él". Si no hay puntos de referencia al objeto (referencia cero), el objeto será reciclado por el mecanismo de recolección de basura.
Por ejemplo
La copia del código es la siguiente:
var o = {
a: {
B: 2
}
};
// se crean dos objetos, uno se hace referencia como el atributo del otro y el otro se asigna a la variable o
// Obviamente, ninguno de ellos puede ser recolectado por basura
var o2 = o; / la variable O2 es la segunda referencia a "este objeto"
o = 1; // Ahora, la referencia original de "este objeto" se reemplaza por O2
var oa = o2.a;
// Ahora, hay dos referencias a "este objeto", uno es O2 y el otro es OA
o2 = "yo" ;/ el objeto original ahora es cero referencia
// Se puede reciclar
// Sin embargo, el objeto de su propiedad A todavía está referenciado por OA, por lo que aún no se puede reciclar
OA = nulo;
// puede ser basura recolectada
Limitación: referencia de reciclaje
Este algoritmo simple tiene una limitación de que si un objeto se refiere a otro (formando una referencia circular), es posible que "ya no lo necesite", pero no se reciclarán.
La copia del código es la siguiente:
función f () {
var o = {};
var o2 = {};
OA = O2;
o2.a = o;
regresar "Azerty";
}
F();
// se crean y se hacen referencia dos objetos, formando un bucle
// No dejarán el alcance de la función después de ser llamado
// para que sean inútiles y se pueden reciclar
// Sin embargo, el algoritmo de conteo de referencia tiene en cuenta que tienen referencias entre sí al menos una vez, por lo que no serán reciclados
Ejemplos prácticos
Es decir, 6, 7 reciclaje de recuento de referencias en objetos DOM. Un problema común para ellos son las filtraciones de memoria:
La copia del código es la siguiente:
var div = document.createElement ("div");
div.OnClick = function () {
Dosomething ();
};
// Div tiene una referencia que apunta a la propiedad de procesamiento de eventos OnClick
// El manejo de eventos también tiene una referencia al DIV al que se puede acceder en el alcance de la función
// Esta referencia circular hará que ambos objetos sean recolectados de basura
Algoritmo de limpieza de marcas
Este algoritmo simplifica "si el objeto ya no es necesario" como "si el objeto está disponible".
Este algoritmo supone establecer un objeto llamado raíz (en JavaScript, la raíz es un objeto global). Regularmente, el recolector de basura comenzará en la raíz, encontrará todos los objetos a los que se hace referencia desde la raíz y luego encontrará los objetos mencionados por estos objetos ... A partir de la raíz, el recolector de basura encontrará todos los objetos que se pueden obtener y todos los objetos que no se pueden obtener.
Este algoritmo es mejor que el anterior, porque los "objetos con cero referencias" siempre no están disponibles, pero por el contrario, no es necesariamente cierto, se refieren a "referencias circulares".
Desde 2012, todos los navegadores modernos han utilizado el algoritmo de recolección de basura limpia de etiquetas. Todas las mejoras en el algoritmo de recolección de basura de JavaScript se basan en mejoras en el algoritmo de limpieza de etiquetas, sin mejorar el algoritmo de limpieza de etiquetas en sí y su definición simplificada de si el objeto ya no es necesario.
Las referencias circulares ya no son un problema
En el ejemplo anterior, después de que la llamada de la función regresa, ambos objetos no se pueden recuperar del objeto global. Por lo tanto, serán reciclados por el recolector de basura.
El segundo ejemplo también, una vez que el Div y su procesamiento de eventos no sean recuperados de la raíz, serán reciclados por el recolector de basura.
Limitación: los objetos deben ser explícitamente no disponibles
Aunque esto es una limitación, rara vez se rompe, por lo que, en realidad, a pocas personas se preocupan por el mecanismo de recolección de basura.