AngularJS: Wie kann man korrekt mit Direktiven, Scopes und Bindings arbeiten, um Speicherlecks zu vermeiden?

8

Ich versuche eine Lösung für ein AngularJS-App-Speicherleck zu finden. Da ich neu in der AngularJS-Welt bin, weiß ich nicht wirklich, wo ich anfangen soll und wo ich meinen Code korrigieren und optimieren kann.

Ich versuche, Ihnen zuerst eine kleine Beschreibung der Anwendung zu geben. Danach werde ich einige Speicherstatistiken veröffentlichen, die ich messen könnte. Ich habe drei Diagnose-Tools verwendet, um den belegten Speicher zu messen: Windows (7) Task Manager, Firefox über: Speicher und den Firefox Extension MemChaser.

Anwendung

  • Die Anwendung ist in eine Seite eingebettet, sollte einmal geladen werden und mindestens 24 Stunden dort verbleiben
  • Die Daten werden kontinuierlich in einem Intervall von 1 bis 60 Minuten über eine $ http () Ajax-Anfrage
  • geladen
  • Die Daten sind ein JSON-Objekt mit einer hierarchischen Struktur
  • Für jede Ebene dieser Hierarchie gibt es eine benutzerdefinierte Komponente (mit einem isolierten Bereich)
  • ausgewählte Teile der Daten werden bemerkt und über eine Ajax-Anfrage hinaus behalten
  • Die meisten Direktiven laden eine HTML-Datei (über $ http () ), um sie als dort Vorlage
  • zu kompilieren

Statistiken

  • Windows Task-Manager

      

    Der von Firefox verwendete Speicher erhöht sich um 50 - 100 MB pro Stunde.

  • über: Speicher

    %Vor%
  • MemChaser 0.5.2.1

    %Vor%
      

    Resident : Vom Prozess verwendeter Speicher, der im physischen Speicher vorhanden ist.    iGC : Dauer der letzten Garbage-Collector-Aktivität.    CC : Dauer der Kollektoraktivität des letzten Zyklus.

Diese Ergebnisse sind ziemlich dramatisch und es scheint, als ob der Fahrradsammler den besten Hinweis gibt. Wenn ich meine App ohne die Ansicht (nur die Ajax-Anfrage) starte, passiert nichts Dramatisches. Wenn ich das Laden der dynamischen Vorlage deaktiviere, gibt es keinen deutlichen Unterschied zur Version mit dynamischen Vorlagen. Es scheint also, dass diese beiden Themen nicht die Ursache sind.

Meine Idee: Mit jeder Ajax-Anfrage werden neue Bereiche und DOM-Knoten erstellt. Die DOM-Knoten können anschließend erstellt werden, aber die Bereiche mit ihren Daten sind wahrscheinlich noch im Speicher vorhanden. Ist das ein mögliches Szenario und eine Ursache für mein Speicherleck?

Wie sollte ich also richtig mit AngularJS-Direktiven, Scopes und Bindings arbeiten, um Speicherlecks wie diese zu vermeiden?

Ich wäre sehr sehr erfreut über jede Hilfe.

Tobias

    
user1071828 30.10.2013, 12:43
quelle

1 Antwort

3

Ich verwende die Chrome-Erweiterung AngularJS Batarang , um Sie beim Debuggen dieser Art von Problemen zu unterstützen. Überwachen Sie die Registerkarten "Modelle" und "Leistung" dieser Erweiterung, um alle nicht erreichbaren oder auslaufenden Bereiche abzurufen. Stellen Sie sicher, wenn Sie keinen bestimmten Bereich mehr benötigen, den Ihr $ zerstören . Z.B. Sehen Sie, wie ngRepeat dies tut .

Aus der Dokumentation:

  

$ destroy ()

     

Entfernt den aktuellen Bereich (und alle untergeordneten Elemente) vom übergeordneten Bereich   Umfang. Die Entfernung bedeutet, dass Aufrufe von $ digest () nicht mehr ausgeführt werden   propagieren Sie auf den aktuellen Umfang und seine Kinder. Entfernen bedeutet auch   dass der aktuelle Bereich für die Garbage Collection geeignet ist.

     

$ destroy () wird normalerweise von Direktiven wie ngRepeat für verwendet   Verwalten des Abrollens der Schleife. Kurz bevor ein Bereich ist   zerstört, wird in diesem Bereich ein $ destroy-Ereignis gesendet   Anwendungscode kann einen $ destroyer-Event-Handler registrieren, der geben wird   Es ist eine Chance, die notwendige Säuberung durchzuführen. Beachten Sie, dass,   AngularJS gibt es auch ein $ destroy jQuery-Ereignis, das verwendet werden kann   bereinigen DOM-Bindungen, bevor ein Element aus dem DOM entfernt wird.

Und

  

$ destroy () muss für einen Bereich aufgerufen werden, wenn es für den Bereich gewünscht wird   und seine Kindbereiche sind dauerhaft vom Elternteil getrennt und   hören Sie damit auf, an der Erkennung und dem Empfang von Modelländerungen teilzunehmen   Benachrichtigung durch Aufruf.

    
Beyers 30.10.2013 13:30
quelle