remove - ¿Por qué jquery pierde memoria tan mal?
remove focus jquery (1)
Esta es una especie de continuación de una pregunta que publiqué la semana pasada: llamada simple jQuery Ajax filtra memoria en Internet Explorer
Me encanta la sintaxis de jquery y todas sus bonitas funciones, pero he estado teniendo problemas con una página que actualiza automáticamente las celdas de la tabla a través de llamadas ajax que pierden memoria.
Así que creé dos páginas de prueba simples para experimentar. Ambas páginas hacen una llamada ajax cada .1 segundos. Después de cada llamada ajax exitosa, se incrementa un contador y se actualiza el DOM. La secuencia de comandos se detiene después de 1000 ciclos.
Uno usa jquery para la llamada ajax y para actualizar el DOM. El otro usa la API de Yahoo para el ajax y hace un document.getElementById (...). InnerHTML para actualizar el DOM.
La versión de jquery pierde mal la memoria. Corriendo en goteo (en XP Home con IE7), comienza en 9MB y termina en aproximadamente 48MB, con la memoria creciendo linealmente todo el tiempo. Si hago un comentario sobre la línea que actualiza el DOM, aún termina en 32MB, sugiriendo que incluso las simples actualizaciones de DOM pierden una cantidad significativa de memoria. La versión sin jquery comienza y finaliza a aproximadamente 9 MB, independientemente de si actualiza el DOM.
¿Alguien tiene una buena explicación de lo que está causando que jquery gotee tan mal? ¿Me estoy perdiendo algo obvio? ¿Hay alguna referencia circular de la que no tenga conocimiento? ¿O simplemente jquery tiene algunos problemas serios de memoria?
Aquí está la fuente para la versión con fugas (jquery):
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load(''jquery'', ''1.4.2'');
</script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
$.ajax({ url: ''/html/delme.x'',
type: ''GET'',
success: incrementCounter
});
}
function incrementCounter(data) {
if (counter<1000) {
counter++;
$(''#counter'').text(counter);
setTimeout(leakTest,100);
}
else $(''#counter'').text(''finished.'');
}
</script>
</head>
<body>
<div>Why is memory usage going up?</div>
<div id="counter"></div>
</body>
</html>
Y aquí está la versión sin fugas:
<html>
<head>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/connection/connection_core-min.js"></script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
YAHOO.util.Connect.asyncRequest(''GET'',
''/html/delme.x'',
{success:incrementCounter});
}
function incrementCounter(o) {
if (counter<1000) {
counter++;
document.getElementById(''counter'').innerHTML = counter;
setTimeout(leakTest,100);
}
else document.getElementById(''counter'').innerHTML = ''finished.''
}
</script>
</head>
<body>
<div>Memory usage is stable, right?</div>
<div id="counter"></div>
</body>
</html>
Mi primer pensamiento sería que tiene algo que ver con la forma en que el método jquery ajax:
a. crea referencias circulares, especialmente malas para IE
segundo. crea propiedades en objetos internos que no se pueden eliminar debido a la forma en que se crearon y la configuración de la propiedad DontDelete. Consulte esto para obtener más información: http://perfectionkills.com/understanding-delete/
De cualquier forma, se evitaría que el recolector de basura recogiera la basura, lo que provocaría una fuga de memoria fuera de control, especialmente si la función sospechosa se ejecuta con frecuencia.