1. Mecanismo de reciclaje de basura - GC
JavaScript tiene un mecanismo automático de recolección de basura (GC: recolección de basura), lo que significa que el entorno de ejecución es responsable de administrar la memoria utilizada durante la ejecución del código.
Principio: El recolector de basura periódicamente (periódico) encuentra variables que no están en uso y luego libera su memoria.
El mecanismo de la recolección de basura de JavaScript es muy simple: descubra variables que ya no se usan y luego liberen la memoria que ocupa. Sin embargo, este proceso no es en tiempo real porque su sobrecarga es relativamente grande, por lo que el recolector de basura se ejecutará periódicamente a intervalos de tiempo fijos .
Las variables que ya no se usan son variables que terminan el ciclo de vida. Por supuesto, solo pueden ser variables locales. El ciclo de vida de la variable global no terminará hasta que el navegador desinstale la página. Las variables locales solo existen durante la ejecución de la función, y en este proceso, el espacio correspondiente se asignará para las variables locales en la pila o montón para almacenar sus valores, y luego estas variables se usan en la función hasta el final de la función. Sin embargo, debido a las funciones internas en el cierre, las funciones externas no pueden considerarse finales.
Expliquemos el código:
function fn1 () {var obj = {name: 'Hanzichi', edad: 10};} function fn2 () {var obj = {name: 'hanzichi', edad: 10}; return obj;} var a = fn1 (); var b = fn2 ();Veamos cómo se ejecuta el código. Primero, se definen dos funciones, llamadas FN1 y FN2. Cuando se llama a FN1, ingresar al entorno FN1 abrirá un objeto de almacenamiento de memoria {nombre: 'Hanzichi', edad: 10}. Cuando la llamada está terminada y el entorno FN1 está fuera, el bloque de basura liberará automáticamente el bloque de memoria en el motor JS; Durante el proceso de FN2 que se llama, el objeto devuelto es apuntando por la variable global B, por lo que no se lanzará el bloque de memoria.
Aquí surge la pregunta: ¿Qué variable es inútil? Por lo tanto, el recolector de basura debe rastrear qué variable es inútil y marcar variables que ya no son útiles para recuperar su memoria en el futuro. Las estrategias para las variables inútiles utilizadas a la etiqueta pueden diferir por implementación, y generalmente hay dos formas de hacerlo: marcar el espacio libre y el recuento de referencias. El conteo de cotizaciones no es muy común, la compensación de marca se usa más comúnmente.
2. Marca clara
El método de recolección de basura más utilizado en JS es la eliminación de marcas. Cuando una variable ingresa al entorno, por ejemplo, declara una variable en una función, marca la variable como "Ingrese al entorno". Hablando lógicamente, la memoria ocupada por las variables que ingresan al entorno no se puede liberar, ya que se pueden usar mientras el flujo de ejecución ingrese al entorno correspondiente. Y cuando una variable abandona el medio ambiente, se marca como "fuera del medio ambiente".
función test () {var a = 10; // está marcado, ingrese al entorno var b = 20; // está marcado, ingrese al entorno} test (); // Después de la ejecución, A y B están marcados, dejan el medio ambiente y se recicla.Cuando se ejecuta el recolector de basura, marca todas las variables almacenadas en la memoria (por supuesto, se puede usar cualquier método de marcado). Luego elimina las etiquetas (cierres) de las variables en el entorno y las variables a las referencias por variables en el entorno. Las variables marcadas después de esto se considerarán como variables listas para eliminarse porque las variables en el entorno ya no pueden acceder a estas variables. Finalmente, el recolector de basura completa el trabajo de compensación de memoria, destruyendo esos valores marcados y recuperando el espacio de memoria que ocupan.
Hasta ahora, las implementaciones JS de IE, Firefox, Opera, Chrome y Safari utilizan estrategias de recolección de basura que limpian marcas o estrategias similares, pero los intervalos de tiempo de la recolección de basura son diferentes entre sí.
3. Recuento de citas
El significado del recuento de referencias es realizar un seguimiento del número de veces que se hace referencia a cada valor. 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. On the contrary, if the variable containing the reference to this value takes another value, the number of references to this value is reduced by 1. When the number of references to this value becomes 0, it means that there is no way to access the value again, so the memory El espacio que ocupa se puede recuperar. De esta manera, cuando el recolector de basura se ejecuta nuevamente la próxima vez, libera la memoria que valora con 0 referencias.
función test () {var a = {}; // El número de referencias de a es 0 var b = a; // El número de referencias de a es 1 var c = a; // El número de referencias de A es 1, y el número de referencias de A es 1, y el número de referencias de A es 1, y el número de referencias de A es 2 var B = {}; // El número de referencias de A es 1, y el número de referencias de A es 1}Netscape Navigator3 fue el primer navegador en utilizar la estrategia de conteo de referencia, pero pronto encontró un problema grave: referencias circulares. Una referencia circular se refiere a un objeto A que contiene un puntero al objeto B, y el objeto B también contiene una referencia al objeto A.
función fn () {var a = {}; var b = {}; a.pro = b; b.pro = a;} fn ();Los tiempos de referencia de A y B arriba son 2. Después de que se ejecuta fn (), ambos objetos han abandonado el entorno. No hay problema en el modo de compensación de marca. Sin embargo, bajo la estrategia de conteo de referencia, porque los tiempos de referencia de A y B no son 0, la memoria no será recolectada por el recolector de basura. Si la función FN se llama en grandes cantidades, se producirá una fuga de memoria. En IE7 e IE8, la memoria se eleva bruscamente.
Sabemos que algunos objetos en IE no son objetos JS nativos. Por ejemplo, los objetos en DOM y BOM se implementan en forma de objetos COM utilizando C ++, y el mecanismo de recolección de basura de los objetos COM adopta una estrategia de conteo de referencia. Por lo tanto, incluso si el motor IE JS adopta una estrategia de compensación de etiquetas, los objetos COM a los que se accede por JS todavía se basan en la estrategia de conteo de referencia. En otras palabras, mientras los objetos COM estén involucrados en IE, habrá un problema de referencias circulares.
var elemento = document.getElementById ("some_element"); var myObject = new Object (); myObject.e = element; element.o = myObject;Este ejemplo crea una referencia circular entre un elemento DOM y un objeto JS nativo. Entre ellos, la variable myobject tiene un atributo llamado elemento que apunta al objeto del elemento; y el elemento variable también tiene un atributo llamado O Back para referirse a MyObject. Debido a esta referencia circular, incluso si el DOM en el ejemplo se elimina de la página, nunca se reciclará.
Mirando el ejemplo anterior, algunos estudiantes pensaron que era demasiado débil. ¿Quién haría algo tan aburrido? De hecho, ¿lo estamos haciendo?
Window.Onload = function OuterFunction () {var obj = document.getElementById ("elemento"); obj.OnClick = function innerFunction () {};};Este código parece estar bien, pero OBJ se refiere a document.getElementById ("Elemento"), y el método OnClick de document.getElementById (" ¿No está muy oculto?
Solución
La forma más fácil es desferir manualmente el bucle, por ejemplo, la función justo ahora puede hacer esto.
myObject.Element = null; element.o = null;
Window.Onload = function OuterFunction () {var obj = document.getElementById ("elemento"); obj.OnClick = function innerFunction () {}; obj = nulo;};Configurar una variable en NULL significa cortar la conexión entre la variable y el valor al que se hizo referencia previamente. Cuando el recolector de basura se ejecuta la próxima vez, estos valores se eliminan y la memoria que ocupan se recicla.
Cabe señalar que IE9+ no tiene una referencia circular para causar fugas de memoria DOM. Puede ser que Microsoft lo haya optimizado, o el método de reciclaje de DOM ha cambiado.
4. Gestión de la memoria
1. ¿Cuándo se activará la recolección de basura?
El recolector de basura funciona periódicamente. Si la memoria asignada es muy grande, el trabajo de reciclaje será muy difícil. Determinar el intervalo de tiempo de recolección de basura se convierte en una pregunta que vale la pena pensar. La recolección de basura de IE6 funciona de acuerdo con la asignación de memoria. Cuando hay 256 variables, 4096 objetos y 64k cadenas en el medio ambiente, se activará el recolector de basura. Parece muy científico y no es necesario llamar de vez en cuando por un tiempo. A veces es innecesario. ¿No es bueno llamar a pedido así? Pero si hay tantas variables en el entorno, y los scripts son tan complejos y normales ahora, entonces el resultado es que el recolector de basura siempre está funcionando, por lo que el navegador no puede jugar.
Microsoft ha realizado ajustes en IE7. Las condiciones de activación ya no se fijan, sino que se modifican dinámicamente. El valor inicial es el mismo que IE6. Si la asignación de memoria recolectada por el recolector de basura es inferior al 15% de la memoria ocupada por el programa, significa que la mayor parte de la memoria no se puede reciclar. Las condiciones del activador de recolección de basura establecida son demasiado sensibles. En este momento, duplique las condiciones de la calle. Si la memoria recolectada es superior al 85%, significa que la mayor parte de la memoria debe limpiarse hace mucho tiempo. En este momento, las condiciones de activación se retroceden. Esto hace que el reciclaje de basura funcione más funciones
2. Solución de GC razonable
1) La solución GC básica del motor JavaScript es (GC simple): marca y barrido, es decir::
2) Defectos de GC
Al igual que otros idiomas, la política de GC de JavaScript no puede evitar un problema: cuando GC, deja de responder a otras operaciones, lo cual es por razones de seguridad. El GC de JavaScript es de 100 ms o incluso arriba, lo cual es bueno para aplicaciones generales, pero para los juegos JS, las aplicaciones que requieren alta coherencia son problemáticas. Esto es lo que el nuevo motor necesita para optimizar: evite la respuesta de detención a largo plazo causada por GC.
3) Estrategia de optimización de GC
El tío David introdujo principalmente dos soluciones de optimización, y estas son también las dos soluciones de optimización más importantes:
(1) generación GC)
Esto es consistente con la idea de la estrategia de reciclaje de Java. El propósito es distinguir entre objetos "temporales" y "persistentes"; Reciclar más áreas de "objeto temporal" y áreas menos "objetos tenuidos", reduzca los objetos que deben atravesar cada vez, reduciendo así el tiempo dedicado a los GC cada vez. Como se muestra en la imagen:
Lo que debe agregarse aquí es que para el objeto de generación titular, hay una sobrecarga adicional: migrarla de generación joven a generación titular, y si se hace referencia, la señalización de referencia también debe modificarse.
(2) GC incremental
La idea de este plan es muy simple, que es "tratar un poco cada vez, tratar un poco la próxima vez, y así sucesivamente". Como se muestra en la imagen:
Aunque esta solución lleva un corto tiempo, tiene muchas interrupciones, lo que trae el problema del cambio de contexto frecuente.
Debido a que cada solución tiene sus escenarios y desventajas aplicables, en las aplicaciones reales, la solución se seleccionará de acuerdo con la situación real.
Por ejemplo: cuando la relación (objeto/s) es baja, la frecuencia de la ejecución de GC se interrumpe y el GC simple es menor; Si una gran cantidad de objetos se "sobreviven" durante mucho tiempo, la ventaja del procesamiento generacional no es excelente.
El artículo anterior comprende integralmente el mecanismo de reciclaje de recolección de basura de Javascirp es todo el contenido que comparto con ustedes. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.