2008-12-04 5 views
2

Application côté client Javascript.Nettoyage de fuite de mémoire JavaScript dans window.unload

essayer d'éliminer les fuites de mémoire conduit à un code laid (pour le moins).

Je suis en train de nettoyer la place en window.unload sur chambouler tout le code en essayant de les éviter.

Nous utilisons principalement element.onevent=function(){..}; modèle, qui se traduit par la fermeture (la plupart du temps voulu) et fuite de mémoire.

Nous n'utilisons pas les frameworks javascript.

Y a-t-il des idées sur la façon de nettoyer correctement à la sortie?

Est-ce que quelqu'un fait de même ou essayez-vous de les éviter?

Répondre

2

La meilleure solution est pour vous de déployer votre propre méthode qui gère la gestion des événements. Par conséquent, lorsque vous attachez un gestionnaire d'événements, votre méthode peut garder une trace de tous les événements ajoutés. Au déchargement, il peut annuler l'inscription de tous les gestionnaires. Je sais que vous avez dit que vous n'utilisez pas de bibliothèques, mais vous pouvez utiliser leur code comme source d'inspiration. Ext-js le fait lorsque vous utilisez Ext.EventMgr.addListener.

Voici un obj EvtMgr simple que vous pouvez utiliser pour commencer. C'est très simpliste, je ne peux pas tout écrire pour vous ici. N'hésitez pas à poser des questions sur les choses que vous aimeriez et ne savent pas faire. Notez également que je n'utiliserais pas la méthode element.onclick car vous ne pouvez ajouter qu'un seul gestionnaire. Je le fais de cette façon parce que vous avez dit que c'est comme ça que vous le faites.

var EvtMgr = (function(){ 
    var listenerMap = {}; 

    // Public interface 
    return { 
    addListener: function (evtName, node, handler) { 
     node["on" + evtName] = handler; 
     var eventList = listenerMap[evtName]; 
     if (!eventList) { 
     eventList = listenerMap[evtName] = []; 
     } 
     eventList.push(node); 
    }, 

    removeAllListeners: function() { 
     for (var evtName in listenerMap) { 
     var nodeList = listenerMap[evtName]; 
     for (var i=0, node; node = nodeList[i]; i++) { 
      node["on" + evtName] = null; 
     } 
     } 
    } 
    } 
})(); 

Aussi, méfiez-vous que les gestionnaires avec les fermetures ne sont pas la seule façon de créer des fuites.Voir mon commentaire sur cette question Javascript memory leaks after unloading a web page

Aussi, je ne comprends pas pourquoi certaines personnes ont peur des bibliothèques. jquery est minuscule, le noyau ext est aussi. Ils peuvent être dangereux si vous les utilisez sans comprendre js. Mais si vos compétences js sont solides, vous économisez beaucoup de travail en réutilisant leur code. Je suis sous le capot d'ext-js tous les jours quand j'ai besoin de comprendre comment quelque chose est fait. C'est ainsi que je vous ai donné ces quelques lignes de code.

Un autre point à considérer lors de la gestion des fuites de mémoire est de vous assurer de supprimer les gestionnaires lors de la suppression d'éléments du DOM (node.innerHTML ou de toute autre manière). Si vous faites cela, vous devez supprimer les gestionnaires des nœuds que vous avez supprimés du DOM. Il y a du travail pour que cela fonctionne, mais cela devrait faire partie de votre stratégie.

0

Je ne suis pas sûr de ce que vous voulez dire avec le nettoyage, car JavaScript a une gestion automatique de la mémoire. Mais de toute façon, si je comprends bien, après que la fenêtre est déchargée, toute la mémoire associée à JS est également libérée. Après tout, il n'y a plus de JS s'exécutant depuis une page après son déchargement, n'est-ce pas?

+0

désolé, non! Il y a deux GC (javascript et DOM). Travailler indépendamment. Si vous connectez des objets javascript et DOM (nous le faisons tout le temps), une fuite se produit. – pkario

0

De la plupart de mes enquêtes sur ce, il n'y a pas de bonne façon de le faire .. chaque navigateur individu a sa propre mise en œuvre de la collecte des ordures.

Firefox est pas si mal, mais IE6 par exemple est terrible .. essayer de créer quoi que ce soit plus de 60 objets et IE6 deviendra très lent.

Juste une de ces choses, j'en suis venu à accepter.

1

Une solution pour éviter les fuites de mémoire avec des événements est la délégation. En un mot, vous attachez votre gestionnaire d'événements à un objet parent au lieu des enfants. En raison de la propagation, un clic sur un enfant sera également enregistré comme un clic sur le parent, ce qui déclenchera votre gestionnaire. En vérifiant l'attribut cible de l'événement, vous pouvez alors décider quoi en faire.

Étant donné que le gestionnaire est attaché au parent, vous pouvez ajouter ou supprimer des enfants sans se soucier de fuites.

Une explication plus approfondie peut être trouvée ici: http://www.robertnyman.com/2008/05/04/event-delegation-with-javascript/

Une démo ici: http://www.robertnyman.com/test/event-delegation/event-delegation.html