Voici une page web très simple qui fait fuir la mémoire dans IE8 en utilisant jQuery (je détecte les fuites de mémoire en regardant l'utilisation de la mémoire de mon processus iexplore.exe augmenter au fil du temps dans le gestionnaire des tâches de Windows) :
<html>
<head>
<title>Test Page</title>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<script type="text/javascript">
function resetContent() {
$("#content div").remove();
for(var i=0; i<10000; i++) {
$("#content").append("<div>Hello World!</div>");
}
setTimeout(resetTable, 2000);
}
$(resetContent);
</script>
<div id="content"></div>
</body>
</html>
Apparemment, même en appelant le jQuery.remove()
Je constate toujours des fuites de mémoire. Je peux écrire ma propre fonction de suppression qui ne subit aucune fuite de mémoire comme suit :
$.fn.removeWithoutLeaking = function() {
this.each(function(i,e){
if( e.parentNode )
e.parentNode.removeChild(e);
});
};
Cela fonctionne parfaitement et n'entraîne aucune perte de mémoire. Alors pourquoi jQuery fait-il fuir de la mémoire ? J'ai créé une autre fonction de suppression basée sur jQuery.remove()
et cela provoque effectivement une fuite :
$.fn.removeWithLeakage = function() {
this.each(function(i,e) {
$("*", e).add([e]).each(function(){
$.event.remove(this);
$.removeData(this);
});
if (e.parentNode)
e.parentNode.removeChild(e);
});
};
Il est intéressant de noter que la fuite de mémoire semble être causée par l'appel de each que jQuery inclut pour éviter les fuites de mémoire dues aux événements et aux données associés aux éléments du DOM qui sont supprimés. Lorsque j'appelle la fonction removeWithoutLeaking
alors ma mémoire reste constante dans le temps, mais lorsque j'appelle la fonction removeWithLeakage
au lieu de ça, ça continue de croître.
Ma question est, qu'en est-il de chaque appel
$("*", e).add([e]).each(function(){
$.event.remove(this);
$.removeData(this);
});
pourrait être à l'origine de la fuite de mémoire ?
EDIT : Correction d'une erreur de frappe dans le code qui, après un nouveau test, s'est avérée n'avoir aucun effet sur les résultats.
NOUVELLE ÉDITION : J'ai rempli un rapport de bogue avec le projet jQuery, puisque cela semble être un bogue de jQuery : http://dev.jquery.com/ticket/5285