Maison >interface Web >js tutoriel >Une discussion détaillée des compétences JavaScript en matière de fuites de mémoire_javascript

Une discussion détaillée des compétences JavaScript en matière de fuites de mémoire_javascript

WBOY
WBOYoriginal
2016-05-16 16:31:281117parcourir

1. Qu'est-ce qu'une fermeture et la chaîne de portée impliquée dans la fermeture ne sera pas discutée ici.

2. Mécanisme de récupération de place JavaScript

JavaScript n'a pas besoin de libérer manuellement de la mémoire, il utilise un mécanisme automatique de récupération de place (garbage collection). Lorsqu'un objet est inutile, c'est-à-dire lorsqu'aucune variable du programme ne fait référence à l'objet, la variable sera libérée de la mémoire.

Copier le code Le code est le suivant :

vars = [1, 2,3];
var s = nul;
// De cette façon, le tableau d'origine [1,2,3] sera libéré.

3. Référence circulaire

Trois objets A, B, C

AàBàC : Un certain attribut de A fait référence à B, et C est également référencé par un attribut de B. Si A est effacé, alors B et C sont également libérés.

AàBàCàB : Ici, un certain attribut de C est ajouté pour référencer l'objet B. Si cela doit effacer A, alors B et C ne seront pas libérés car une référence circulaire est générée entre B et C.

Copier le code Le code est le suivant :

var une = {};
a.pro = { a:100 };
a.pro.pro = {b:100};
une = nul
//Dans ce cas, {a:100} et {b:100} sont également publiés en même temps.
                                                                    var obj = {};
Obj.pro = { a : 100 };
Obj.pro.pro = { b : 200 };
var deux = obj.pro.pro;
Obj = nul
//Dans ce cas, {b:200} ne sera pas publié, mais {a:100} sera publié.

4. Références circulaires et fermetures

Copier le code Le code est le suivant :
fonction externe(){
var obj = {};
fonction interne(){
//L'objet obj est référencé ici
>
         obj.inner = inner;
>

Il s'agit d'une référence circulaire extrêmement cachée. Lorsque external est appelé une fois, deux objets, obj et inner, seront créés à l'intérieur. La propriété inner de obj fait référence à inner ; de la même manière, inner fait également référence à obj. C'est parce que obj est toujours dans l'environnement fermé de innerFun. soyez précis, cela est dû à la "chaîne de portée" unique de JavaScript.

Par conséquent, les fermetures sont très faciles à créer des références circulaires. Heureusement, JavaScript peut très bien gérer de telles références circulaires.

5. Fuite de mémoire dans IE

Il existe plusieurs types de fuites de mémoire dans IE, et vous trouverez des explications détaillées ici (

http://msdn.microsoft.com/en-us/library/bb250448.aspx).

Un seul d’entre eux est abordé ici, à savoir la fuite de mémoire provoquée par référence circulaire, car c’est la situation la plus courante.

Lorsqu'il existe une référence circulaire entre un élément DOM ou un objet ActiveX et un objet JavaScript normal, IE a des difficultés particulières à libérer de telles variables. Il est préférable de couper manuellement la référence circulaire. Ce bug a été corrigé dans IE. 7 (

http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html).

« IE 6 souffrait de fuites de mémoire lorsqu'une référence circulaire entre plusieurs objets, parmi lesquels au moins un nœud DOM, était créée. Ce problème a été résolu dans IE 7. »

.

Si dans l'exemple ci-dessus (point 4) obj ne fait pas référence à un objet Fonction JavaScript (interne), mais à un objet ActiveX ou à un élément Dom, la référence circulaire formée dans IE ne peut pas être libérée.

Copier le code Le code est le suivant :

Fonction init(){
        var elem = document.getElementByid( 'id' );
          elem.onclick = function(){
alert('homme-pluie');
//L'élément elem
est référencé ici         };
>

Elem fait référence à sa fonction d'écoute d'événements de clic, qui fait également référence à l'élément elem via sa chaîne de portée. De cette façon, ces références circulaires ne seront pas publiées même si vous quittez la page actuelle dans IE.

6.Solution

La méthode de base consiste à effacer manuellement cette référence circulaire. Voici un exemple très simple. Dans une application réelle, vous pouvez créer vous-même une fonction addEvent() et effacer toutes les liaisons d'événements sur l'événement de déchargement de la fenêtre.

Copier le code Le code est le suivant :

fonction externe(){
         var one = document.getElementById( 'one' );
         one.onclick = function(){};
>
​ window.onunload = function(){
         var one = document.getElementById( 'one' );
         one.onclick = null;
};

Autres méthodes (par : Douglas Crockford)

Copier le code Le code est le suivant :

/**
* Traverser un nœud d'élément et tous ses éléments descendants
*
* @param Elem node Le nœud d'élément à effacer
* @param function func La fonction de traitement
*
​*/
function walkTheDOM (noeud, func) {
func(nœud);
node = node.firstChild;
while (nœud) {
         walkTheDOM(node, func); Node = node.nextSibling;
}
}
/**
* Effacez toutes les références aux nœuds dom pour éviter les fuites de mémoire
*
* @param Elem node Le nœud d'élément à effacer
*
​*/
fonction purgeEventHandlers (nœud) {
walkTheDOM(nœud, fonction (e) {
pour (var n dans e) {                                    Si (type de e[n] ===
                      'fonction') {
                  e[n] = null;
            }
>
});


Ce qui précède présente le contenu pertinent et les solutions aux fuites de mémoire JavaScript. Les amis dans le besoin peuvent s'y référer.
Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn