memoria liberar leak how collector javascript memory-leaks event-handling

liberar - Los controladores de eventos Javascript siempre aumentan el uso de la memoria del navegador



javascript memory leak analyzer (3)

Editar: Tras un examen más detallado, Firefox no parece estar haciendo esto, pero definitivamente Chrome sí lo hace. Supongo que es solo un error con un nuevo navegador: para cada evento, también se produce una lectura de E / S en Chrome, pero no en FF.

Cuando cargo la siguiente página en un navegador (lo he probado en Chrome y Firefox 3 en Vista) y muevo el mouse alrededor de la memoria, siempre aumenta y parece que nunca retrocede.

Es esto:

  1. comportamiento esperado de un navegador
  2. una pérdida de memoria en el navegador o
  3. una pérdida de memoria en el código presentado?

.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>test</title> </head> <body> <script> var createEl = function (i) { var el = document.createElement("div"); var t = document.createTextNode(i.toString()); el.appendChild(t); t=null; el.id=i.toString(); var fn = function (e) {}; el.addEventListener("mouseover", fn, false); //el.onmouseover = fn; fn = null; try{ return el; } finally{ el=null; } //return (el = [el]).pop(); }; var i,x; for (i= 0; i < 100; i++){ x = createEl(i) document.body.appendChild(x); x = null; } </script> </body> </html>

El (el = [el].pop()) y las ideas try/finally son ambos de aquí , aunque tampoco parecen ayudar, comprensiblemente, ya que solo están destinados a ser correcciones ie6.

También he experimentado con el uso de los métodos addEventListener y onmouseover para agregar los eventos. La única forma que he encontrado para evitar que la memoria se incremente es comentar las dos líneas de código.


Bueno, esta no es la forma en que manejaría esto, y no puedo reproducir el comportamiento, así que todo lo que puedo decirte es que el problema que estás teniendo en memoria es probable debido a lo que sea que esté en la función fn , y a menos que sea un cierre debe definir fn fuera de la función createEl y simplemente haciendo referencia a ella dentro, por lo que solo existe una instancia única de eso en la memoria.

Sin embargo, necesitas manejar mejor el enlace de eventos (esto no es seguro para Xbrowser - en este punto dudo en sugerir jQuery), y todo ese (el =[el]).pop() apesta a vudú, aunque yo '' Estoy feliz de ser corregido si alguien puede explicar exactamente lo que logra.


Las fugas de memoria relacionadas con los controladores de eventos están relacionadas, en términos generales, con los recintos. En otras palabras, asociar una función a un controlador de eventos que apunte a su elemento puede evitar que los navegadores recolecten basura. (Afortunadamente, la mayoría de los navegadores más nuevos han "aprendido el truco" y ya no pierden memoria en este escenario, ¡pero hay muchos navegadores antiguos flotando por ahí!)

Tal recinto podría verse así:

var el = document.createElement("div"); var fnOver = function(e) { el.innerHTML = "Mouse over!"; }; var fnOut = function(e) { el.innerHTML = "Mouse out."; }; el.addEventListener("mouseover", fnOver, false); el.addEventListener("mouseout", fnOut, false); document.getElementsByTagName("body")[0].appendChild(el);

El hecho de que fnOver y fnOut a su alcance adjunto para hacer referencia a el es lo que crea un gabinete (dos, en realidad, uno para cada función) y puede provocar la fuga de navegadores. Su código no hace nada como esto, por lo que no crea recintos, por lo que no debe provocar un escape (de buen comportamiento) en el navegador.

Solo uno de los fastidiosos del software beta, supongo. :-)


fn es un cierre incluso sin código. Por ejemplo, intente depurar con Firebug y configure el punto de interrupción dentro de esa función. Todas las variables definidas en el cierre (código fn + variables que cuelgan alrededor = cierre) son teóricamente accesibles (aunque no sé cómo acceder a ellas en la práctica).