63 votes

Pourquoi jQuery perd-il tellement de mémoire?

C'est une sorte de suite à une question que j'ai posté la semaine dernière: http://stackoverflow.com/questions/2429056/simple-jquery-ajax-call-leaks-memory-in-ie

J'aime le jquery, la syntaxe et l'ensemble de ses fonctionnalités intéressantes, mais j'ai de la difficulté avec une page qui met automatiquement à jour les cellules d'un tableau via des appels ajax fuite de mémoire.

J'ai donc créé deux pages de test pour l'expérimentation. Les deux pages faire un appel ajax chaque .1 secondes. Après chaque appel ajax, un compteur est incrémenté et le DOM est mis à jour. Le script s'arrête après 1000 cycles.

On utilise jquery pour l'appel ajax et de mettre à jour le DOM. L'autre utilise l'API Yahoo pour l'ajax et un document.getElementById(...).innerHTML pour mettre à jour le DOM.

La version jquery fuites de mémoire de mal. L'exécution en goutte à goutte (sur XP Home avec IE7), il commence à 9MB et se termine à environ 48 MO de mémoire qui augmente de façon linéaire tout le temps. Si je commente la ligne qui met à jour le DOM, il reste les finitions à 32 MO, ce qui suggère que même de simples DOM mises à jour de la fuite d'une quantité importante de mémoire. Le non-jquery version commence et se termine à environ 9 MO, indépendamment du fait qu'il met à jour les DOM.

Quelqu'un aurait-il une bonne explication de ce qui est à l'origine de jquery pour la fuite si mal? Ai-je raté quelque chose d'évident? Est-il une référence circulaire que je ne suis pas au courant? Ou n'jquery tout simplement avoir de sérieux problèmes de mémoire?

Ici est la source de la fuite (jquery) version:

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load('jquery', '1.4.2');
    </script>
    <script type="text/javascript">
      var counter = 0;
      leakTest();
      function leakTest() {
        $.ajax({ url: '/html/delme.x',
                 type: 'GET',
                 success: incrementCounter
               });
      }
      function incrementCounter(data) {
        if (counter<1000) {
          counter++;
          $('#counter').text(counter);
          setTimeout(leakTest,100);
        }
        else $('#counter').text('finished.');
      }
    </script>
  </head>
  <body>
    <div>Why is memory usage going up?</div>
    <div id="counter"></div>
  </body>
</html>

Et ici, c'est le non qui fuit version:

<html>
  <head>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/connection/connection_core-min.js"></script>
    <script type="text/javascript">
      var counter = 0;
      leakTest();
      function leakTest() {
        YAHOO.util.Connect.asyncRequest('GET',
                                        '/html/delme.x',
                                        {success:incrementCounter});
      }
      function incrementCounter(o) {
        if (counter<1000) {
          counter++;
          document.getElementById('counter').innerHTML = counter;
          setTimeout(leakTest,100);
        }
        else document.getElementById('counter').innerHTML = 'finished.'
      }
    </script>
  </head>
  <body>
    <div>Memory usage is stable, right?</div>
    <div id="counter"></div>
  </body>
</html>

8voto

Jessica Jacobs Points 1001

Ma première pensée est qu'elle a quelque chose à voir avec la façon dont le jquery, ajax méthode:

un. crée des références circulaires, particulièrement mauvais pour IE

b. crée des propriétés sur les objets internes qui ne peuvent pas être supprimés en raison de la façon dont ils ont été créés et le réglage de la DontDelete de la propriété. Voir ce pour plus d'info: http://perfectionkills.com/understanding-delete/

De toute façon, le garbage collector seraient pas en mesure de ramasser la poubelle, ce qui entraînerait une perte de contrôle de fuite de mémoire, surtout si le suspect de la fonction est en cours d'exécution fréquemment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X