2009-04-20 13 views
27

Tengo una aplicación que permite a un usuario ver detalles sobre un caso específico sin una devolución de datos. Cada vez que un usuario solicita datos del servidor, despliegue el siguiente marcado.Cómo deshacerse de los elementos DOM en JavaScript para evitar fugas de memoria

<form name="frmAJAX" method="post" action="Default.aspx?id=123456" id="frmAJAX"> 
<div> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" /> 
</div> 
<div> 
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" /> 
</div> 
<div id="inner"> 
<!-- valid info here --!> 
</div> 
</form> 

siguiente que tome lo anterior y InnerHtml a un nuevo elemento DOM, así:

success: function(xhtml) { 
     var tr = document.createElement('tr'); 
     var td = document.createElement('td'); 
     var container = document.createElement('div'); 

     obj.parentNode.parentNode.parentNode.insertBefore(tr, obj.parentNode.parentNode.nextSibling); 

     td.appendChild(container); 
     container.innerHTML = xhtml; 
     tr.appendChild(td); 

pero después de lo anterior, utilizar algunos jQuery para eliminar la Red PEA desagradable basura

$('form:eq(1)').children().each(
    function() { 
     if ($('form:eq(1)').find('div').filter(function() { return $(this).attr('id') == ''; }).remove()); 
    } 
); 

//Capture the remaining children 
var children = $('form:eq(1)').children(); 

// Remove the form 
$('form:eq(1)').remove(); 

// append the correct child element back to the DOM 
parentObj.append(children); 

Mi pregunta es esta: cuando utilizo IESieve, no observo filtraciones reales, sino un número cada vez mayor de elementos DOM (por lo tanto, uso de memoria).

¿Qué puedo mejorar en el lado del cliente para realmente limpiar este desastre? Nota: ambos IE7/8 muestran estos resultados.

EDIT: finalmente conseguí que esto funcionara y decidí escribir un blog post corto con el código fuente completo.

+0

realmente se debe aceptar una respuesta a esta pregunta ahora .... – Blazemonger

+0

puede actualizar URL al blog de correos? – Christian

+1

@Christian acaba de hacer (lo siento por el enlace roto) –

Respuesta

12

La parte engañosa es averiguar dónde todavía existe una referencia a los nodos ofensores.

Lo hace de la manera difícil: agrega todas las marcas a la página y luego elimina las que no desea. Yo lo haría la manera siguiente:

var div = document.createElement('div'); 
// (Don't append it to the document.) 

$(div).html(xhtml); 

var stuffToKeep = $(div).find("form:eq(1)> *").filter(
    function() { 
    return $(this).attr('id') !== ''; 
    } 
); 

parentObj.append(stuffToKeep); 

// Then null out the original reference to the DIV to be safe. 
div = null; 

Esto no está garantizado para detener la fuga, pero es un buen comienzo.

+0

Este es un gran paso adelante porque la mayoría de los elementos de DOM que quedan son los que estaba eliminando y nunca usé. ¡Gracias! –

2

remove() y su tipo solo elimina elementos del DOM. Todavía existen en la memoria en alguna parte.

Este es un problema conocido con AJAX y Web 2.0. Hay poco que puede hacer aparte de diseñar su sitio para asegurarse de que de vez en cuando tenga una actualización de página para borrar todo.

+3

No se puede disponer de ellos de tal manera que cuando el recolector de basura Javascript viene por ahí, estos los elementos se eliminan de la memoria? –

+0

Uno supondría que ese es el caso, pero aparentemente no lo es. – Randolpho

+2

Hmm ... después de algunas investigaciones, puede probar algunas de las soluciones que se analizan en esta página: http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/c76967f0-dcf8-47d0-8984 -8fe1282a94f5 – Randolpho

1

Creo que el "consumo de memoria siempre creciente" es un tanto incomprendido. Tiene que ver con la administración de memoria dentro del navegador (y también en Windows en general) más de lo que tiene que ver con su código JS. Los administradores de memoria generalmente siguen asignando (o evitando liberar) hasta que tienen que hacerlo. En sistemas basados ​​en paginas y mapeo de memoria, asignar y liberar memoria consume mucho tiempo.

De modo que, incluso si sus nodos se liberan de la estructura del documento real y del DOM, apenas hay forma de medirlo desde el propio Windows en "tiempo real".

Prueba esto:

  1. inicio Taskmanager, cambie a la pestaña procesar y ver la memoria de su navegador

  2. carga en un documento HTML que asigna 100.000 nodos, ver crecer el consumo de memoria

  3. Haga clic en un botón en la página que libera todos los nodos. Tenga en cuenta que poco pasa en términos de liberación de memoria.

  4. Ahora minimice la ventana del navegador y maximícela nuevamente.En el 90% de los casos, el navegador ahora vacía la memoria si no la usa y verá cuánto consume realmente.

Usted puede tener un navegador consumir 500 megabytes de RAM (no mencionado ejemplo), pero cuando minimiza y maximiza, se libera todo y de repente que sólo utiliza 50 megabytes.

6
function discardElement(element) { 
    var garbageBin = document.getElementById('IELeakGarbageBin'); 
    if (!garbageBin) { 
     garbageBin = document.createElement('DIV'); 
     garbageBin.id = 'IELeakGarbageBin'; 
     garbageBin.style.display = 'none'; 
     document.body.appendChild(garbageBin); 
    } 
    // move the element to the garbage bin 
    garbageBin.appendChild(element); 
    garbageBin.innerHTML = ''; 
} 

Source

+0

sé que es un poco tarde en el juego ... –

+2

un bello ejemplo de por qué IE Tal chupa ... –

+2

le dan ninguna explicación de por qué esto incluso trabajar. no tiene sentido. – vsync

Cuestiones relacionadas