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.
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
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.
Tags und Links angularjs data-binding angularjs-directive angularjs-scope