recolector memoria liberar leaks ejemplo collector basura javascript garbage-collection

leaks - liberar memoria javascript



¿Qué es la recolección de basura JavaScript? (9)

¿Qué es la recolección de basura JavaScript? ¿Qué es importante que un programador web entienda sobre la recolección de basura de JavaScript para escribir un mejor código?


"En ciencias de la computación, la recolección de basura (GC) es una forma de administración automática de la memoria. El recolector de basura, o simplemente el recolector, intenta reclamar la basura, o la memoria utilizada por objetos a los que la aplicación nunca accederá ni volverá a mutar".

Todos los motores de JavaScript tienen sus propios recolectores de basura, y pueden ser diferentes. La mayoría del tiempo no tiene que lidiar con ellos porque solo hacen lo que se supone que deben hacer.

Escribir un mejor código depende principalmente de lo bien que sepa los principios de programación, el lenguaje y la implementación particular.


¿Qué es la recolección de basura JavaScript?

mira this

¿Qué es importante que un programador web entienda sobre la recolección de basura de JavaScript para escribir un mejor código?

En Javascript no te importa la asignación de memoria y la desasignación. Todo el problema se exige al intérprete de Javascript. Las fugas aún son posibles en Javascript, pero son errores del intérprete. Si está interesado en este tema, puede leer más en www.memorymanagement.org


Buena cita tomada de un blog

El componente DOM es "basura recolectada", al igual que el componente JScript, lo que significa que si crea un objeto dentro de cualquiera de los componentes y luego pierde el rastro de ese objeto, eventualmente se limpiará.

Por ejemplo:

function makeABigObject() { var bigArray = new Array(20000); }

Cuando llama a esa función, el componente JScript crea un objeto (llamado bigArray) que es accesible dentro de la función. Sin embargo, tan pronto como la función regresa, "pierdes la pista" de bigArray porque ya no hay forma de referirse a ella. Bueno, el componente de JScript se da cuenta de que lo has perdido, por lo que bigArray se limpia, su memoria se recupera. El mismo tipo de cosas funciona en el componente DOM. Si dice document.createElement(''div'') , o algo similar, entonces el componente DOM crea un objeto para usted. Una vez que pierda la pista de ese objeto de alguna manera, el componente DOM limpiará lo relacionado.


En Windows puede usar Drip.exe para encontrar fugas de memoria o verificar si su rutina de memoria gratuita funciona.

Es realmente sencillo, solo ingrese la URL de un sitio web y verá el consumo de memoria del procesador IE integrado. Luego presione actualizar, si la memoria aumenta, encuentra una pérdida de memoria en algún lugar de la página web. Pero esto también es muy útil para ver si las rutinas para liberar memoria funcionan para IE.


Eric Lippert escribió una publicación de blog detallada sobre este tema hace un tiempo (además, comparándolo con VBScript ). Más exactamente, escribió sobre JScript , que es la implementación de ECMAScript de Microsoft, aunque es muy similar a JavaScript. Me imagino que puede asumir que la gran mayoría de los comportamientos serían los mismos para el motor de JavaScript de Internet Explorer. Por supuesto, la implementación variará de un navegador a otro, aunque sospecho que podría tomar algunos de los principios comunes y aplicarlos a otros navegadores.

Citado de esa página:

JScript utiliza un recolector de basura de marca y barrido no generacional. Funciona así:

  • Cada variable que está "en el alcance" se llama un "eliminador". Un tesoro puede referirse a un número, un objeto, una cadena, lo que sea. Mantenemos una lista de eliminadores: las variables se mueven a la lista de scav cuando entran en el alcance y salen de la lista de scav cuando están fuera del alcance.

  • De vez en cuando corre el recolector de basura. Primero, coloca una "marca" en cada objeto, variable, cadena, etc., toda la memoria rastreada por el GC. (JScript usa la estructura de datos VARIANT internamente y hay muchos bits extra sin usar en esa estructura, así que solo configuramos uno de ellos).

  • En segundo lugar, borra la marca de los eliminadores y el cierre transitivo de las referencias del eliminador. Por lo tanto, si un objeto del tesoro hace referencia a un objeto que no es del tesoro, borramos los bits en el no-tesoro y en todo lo que se refiere. (Estoy usando la palabra "cierre" en un sentido diferente al de mi publicación anterior).

  • En este punto, sabemos que a toda la memoria aún marcada se le asigna una memoria que no puede ser alcanzada por ninguna ruta desde ninguna variable dentro del alcance. Todos estos objetos están instruidos para derribarse, lo que destruye cualquier referencia circular.

El propósito principal de la recolección de basura es permitir que el programador no se preocupe por la administración de la memoria de los objetos que crea y utiliza, aunque, por supuesto, a veces no se puede evitar, siempre es beneficioso tener al menos una idea aproximada de cómo funciona la recolección de basura. .

Hay algunos puntos particulares a tener en cuenta. El sitio de desarrolladores de Apple tiene algunas pautas al respecto. Dos importantes desde allí:

  • Utilice las declaraciones de eliminación. Siempre que cree un objeto utilizando una nueva declaración, combínelo con una instrucción de eliminación. Esto garantiza que toda la memoria asociada con el objeto, incluido su nombre de propiedad, esté disponible para la recolección de basura. La declaración de eliminación se discute más en "Liberar objetos".
  • Utilice la palabra clave var. Cualquier variable creada sin la palabra clave var se crea en el ámbito global y nunca es elegible para la recolección de basura, lo que presenta la oportunidad de una pérdida de memoria.

Me imagino que las prácticas deberían aplicarse a todos los motores de JavaScript (en diferentes navegadores), aunque como se trata de un sitio de Apple, pueden ser algo específicos de Safari. (¿Quizás alguien podría aclarar eso?)

Espero que ayude.


Según mi conocimiento, los objetos de JavaScript se recolectan periódicamente cuando no quedan referencias al objeto. Es algo que sucede automáticamente, pero si desea ver más sobre cómo funciona, a nivel de C ++, tiene sentido echar un vistazo al código fuente de WebKit o V8

Por lo general, no es necesario que lo piense, sin embargo, en navegadores más antiguos, como IE 5.5 y versiones anteriores de IE 6, y quizás en las versiones actuales, los cierres crearían referencias circulares que, si no se seleccionaban, acabarían consumiendo memoria. En el caso particular al que me refiero con respecto a los cierres, fue cuando agregó una referencia de JavaScript a un objeto dom, y un objeto a un objeto DOM que se refirió nuevamente al objeto JavaScript. Básicamente, nunca se pudo recopilar, y eventualmente causaría que el sistema operativo se vuelva inestable en las aplicaciones de prueba que generaron bloqueos. En la práctica, estas fugas suelen ser pequeñas, pero para mantener su código limpio, debe eliminar la referencia de JavaScript al objeto DOM.

Por lo general, es una buena idea utilizar la palabra clave delete para quitar la referencia inmediata de objetos grandes como los datos JSON que haya recibido y que haya hecho todo lo que necesite hacer, especialmente en el desarrollo web móvil. Esto hace que el siguiente barrido del GC elimine ese objeto y libere su memoria.


Tenga cuidado con las referencias circulares cuando se trata de objetos DOM:

Patrones de pérdida de memoria en JavaScript

Tenga en cuenta que la memoria solo se puede recuperar cuando no hay referencias activas al objeto. Este es un error común con los cierres y los controladores de eventos, ya que algunos motores JS no verifican a qué variables se hace referencia en las funciones internas y solo conservan todas las variables locales de las funciones adjuntas.

Aquí hay un ejemplo simple:

function init() { var bigString = new Array(1000).join(''xxx''); var foo = document.getElementById(''foo''); foo.onclick = function() { // this might create a closure over `bigString`, // even if `bigString` isn''t referenced anywhere! }; }

Una implementación JS ingenua no puede recopilar bigString mientras el controlador de eventos esté presente. Hay varias maneras de resolver este problema, por ejemplo, establecer bigString = null al final de init() ( delete no funcionará para variables locales y argumentos de función: delete elimina propiedades de objetos, y el objeto variable es inaccesible: ES5 en estricto el modo incluso lanzará un error de ReferenceError si intenta eliminar una variable local!).

Recomiendo evitar cierres innecesarios tanto como sea posible si se preocupa por el consumo de memoria.


la recolección de basura (GC) es una forma de administración automática de memoria al eliminar los objetos que ya no son necesarios.

Cualquier proceso relacionado con la memoria sigue estos pasos:

1 - asigne el espacio de memoria que necesita

2 - hacer un poco de procesamiento

3 - liberar este espacio de memoria

Hay dos algoritmos principales que se utilizan para detectar qué objetos ya no son necesarios.

Recolección de basura de recuento de referencias : este algoritmo reduce la definición de "ya no se necesita un objeto" a "un objeto no tiene otro objeto que haga referencia a él", el objeto se eliminará si no hay un punto de referencia.

Algoritmo de marca y barrido : conecta cada objeto a la fuente raíz. cualquier objeto no se conecta a la raíz u otro objeto. este objeto será eliminado.

Actualmente los navegadores más modernos utilizan el segundo algoritmo.


Los tipos de referencia no almacenan el objeto directamente en la variable a la que está asignado, por lo que la variable de objeto en este ejemplo no contiene realmente la instancia del objeto. En su lugar, contiene un puntero (o referencia) a la ubicación en la memoria donde existe el objeto

var object = new Object();

Si asigna una variable a otra, cada variable obtiene una copia del puntero, y ambas siguen haciendo referencia al mismo objeto en la memoria.

var object1 = new Object(); var object2 = object1;

JavaScript es un lenguaje recogido en la basura , por lo que realmente no necesita preocuparse por las asignaciones de memoria cuando utiliza tipos de referencia. Sin embargo, es mejor desreferenciar los objetos que ya no necesita para que el recolector de basura pueda liberar esa memoria. La mejor manera de hacer esto es establecer la variable de objeto en nulo.

var object1 = new Object(); // do something object1 = null; // dereference

La desreferenciación de objetos es especialmente importante en aplicaciones muy grandes que utilizan millones de objetos.

de Los principios del JavaScript orientado a objetos - NICHOLAS C. ZAKAS