Per aggiungere al bobince risposta, ho fatto alcuni test con IE8.
Ho provato quasi tutti gli esempi forniti da http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
Nessuno di loro è che perde la memoria più (almeno non in modo percepibile), salvo l'esempio che rimuove nodi figlio con eventi ancora ad essi connessi.
Questo tipo di esempio penso che sia meglio spiegato da Douglas Crockford nella sua coda2.
Questo ancora perdite di memoria su IE8 ed è abbastanza facile verificare semplicemente eseguendo the test script e guardando Task Manager di Windows - Prestazioni - PF di utilizzo. Vedrete che PF Usage aumenta di quasi 1 MB per loop (molto veloce).
Ma in IE8 memoria viene rilasciato a pagina scarico (come navigazione verso una nuova pagina o ricaricare la stessa pagina) e ovviamente anche se completamente chiusura del browser.
Quindi, per consentire all'utente finale di percepire questa perdita di memoria su IE8 (come prestazioni systerm ridotte), ha bisogno di rimanere sulla stessa pagina per un lungo periodo di tempo, che in alcuni giorni può accadere spesso con AJAX, ma questa pagina deve anche fare centinaia di rimozione di elementi childs con elementi collegati a loro.
prova Douglas Crockford è sottolineando il browser con 10000 nodi aggiunti e poi rimosso, che è eccellente per che vi mostra il problema, ma nella vita reale non ho mai avuto una pagina che ha rimosso più di 10 elementi.INMHO di solito è più veloce usare display: none
invece di rimuovere un intero set di nodi, ecco perché non uso più tanto lo removeChild
.
Perché chi potrebbe essere più interessato alla perdita di memoria IE8 spiegato sopra, ho fatto un altro test e sembra perdite mem non appaiono affatto in IE8 quando si utilizza innerHTML
al posto di appendChild/removeChild
per aggiungere/rimuovi elementi figlio con eventi collegati. Quindi, a quanto pare Douglas Crockford purge function (suggerito da lui per evitare perdite di memoria in IE) non è più necessario in IE8, almeno quando si utilizza innerHTML
...
(CURATE grazie a 4esn0k commento qui sotto) ... inoltre Douglas Crockford purge function non funziona affatto su IE8, nel suo codice var a = d.attributes
restituisce NO onclick
attributi (o qualsiasi altro onevent
attributi) che sono stati aggiunti in fase di esecuzione su IE8 (vengono restituiti su IE7).
Douglas Crockford dice:
"La funzione di spurgo deve essere chiamata prima di rimuovere qualsiasi elemento, sia dal metodo removeChild, oppure impostando la struttura innerHTML."
che fornisco qui il codice per il test:
<body>
<p>queuetest2 similar to the one provided by Douglas Crockford
at http://www.crockford.com/javascript/memory/leak.html
<br>but this one adds/removes spans using innerHTML
instead of appendChild/removeChild.</p>
<div id="test"></div>
<script>
/* ORIGINAL queuetest2 CODE FROM DOUGLAS CROCKFORD IS HERE
http://www.crockford.com/javascript/memory/queuetest2.html */
(function (limit, delay)
{
var n = 0;
var add = true;
function makeSpan(n)
{
var div = document.getElementById('test');
//adding also an inline event to stress more the browser
div.innerHTML = "<span onmouseover=\"this.style.color = '#00ff00';\">" + n + "</span>";
var s = div.getElementsByTagName('span')[0];
s.onclick = function(e)
{
s.style.backgroundColor = 'red';
alert(n);
};
return s;
}
function process(n)
{
if(add)
s = makeSpan(n);
else
s.parentNode.innerHTML = ""; //removing span by clearing the div innerHTML
add = !add;
}
function loop()
{
if (n < limit)
{
process(n);
n += 1;
setTimeout(loop, delay);
}
}
loop();
})(10000, 10);
</script>
</body>
+1: cercato a lungo per questo perl di saggezza. –
@Marco Demaio Hmm, questo http://ecmascript.stchur.com/blogcode/ie_innerhtml_memleak/leak.html perde ancora in IE9 in modalità standard o quirk (win7 64 bit), assicurati di utilizzare Process Explorer quando monitora i byte privati .. sigh .. –
@AlexanderN: in realtà su IE8 WXP la pagina che hai suggerito non perde. Io uso il semplice "Task Manager di Windows" (scheda "Prestazioni") per vedere se la pagina perde, in tal caso si vedrebbe "L'utilizzo di PF" aumentare sempre di più. –