Exemplarische Vorgehensweise: Suchen eines Speicherverlusts (JavaScript)
Diese exemplarische Vorgehensweise führt Sie durch den Prozess zum Identifizieren und Beheben eines einfachen Arbeitsspeicherproblems mithilfe der JavaScript-Speicheranalyse. Die JavaScript-Speicheranalyse ist in Visual Studio für Windows Store-Apps verfügbar, die für Windows mit JavaScript erstellt wurden. In diesem Szenario erstellen Sie eine App, die fehlerhafterweise DOM-Elemente im Speicher behält, anstatt Elemente mit derselben Geschwindigkeit zu löschen, mit der sie erstellt werden.
Obwohl die Ursache für den Speicherverlust in dieser App sehr spezifisch ist, demonstrieren die hier gezeigten Schritte einen Workflow, der normalerweise wirkungsvoll die Objekte isoliert, die den Speicherverlust verursachen.
Ausführen der Test-App zur JavaScript-Speicheranalyse
Wählen Sie in Visual Studio Datei, Neu, Projekt aus.
Wählen Sie im linken Bereich JavaScript und anschließend Windows-Apps, Universelle Apps oder Windows Phone-Apps aus.
Wählen Sie dann im mittleren Bereich die Projektvorlage Leere App aus.
Geben Sie im Feld Name einen Namen wie JS_Mem_Tester an, und wählen Sie dann OK aus.
Öffnen Sie im Projektmappen-Explorer default.html, und fügen Sie den folgenden Code zwischen den <body>-Tags ein:
<div class="wrapper"> <div id="item"></div> <button class="memleak" style="display: block" >Leak Memory</button> </div>
Wichtig
Wenn Sie eine Vorlage für universelle Apps verwenden, müssen Sie HTML- und CSS-Code sowohl in den .Windows- als auch in den .WindowsPhone-Projekten aktualisieren.
Öffnen Sie default.css, und fügen Sie den folgenden CSS-Code hinzu:
.memleak { position: absolute; top: 100px; left: 100px; }
Öffnen Sie default.js, und ersetzen Sie den gesamten Code mit dem folgenden Code:
(function () { "use strict"; var app = WinJS.Application; var activation = Windows.ApplicationModel.Activation; var wrapper; var elem; app.onactivated = function (args) { if (args.detail.kind === activation.ActivationKind.launch) { if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { } else { } args.setPromise(WinJS.UI.processAll()); elem = document.getElementById("item"); wrapper = document.querySelector(".wrapper"); var btn = document.querySelector(".memleak"); btn.addEventListener("click", btnHandler); run(); } }; app.oncheckpoint = function (args) { }; app.start(); function run() { initialize(); load(); } function initialize() { if (wrapper != null) { elem.removeNode(true); } } function load() { var newDiv = document.createElement("div"); newDiv.style.zIndex = "-1"; newDiv.id = "item"; wrapper.appendChild(newDiv); } function btnHandler(args) { run(); } })();
Drücken Sie die F5-TASTE, um das Debuggen zu starten. Überprüfen Sie, dass die Schaltfläche Speicherverlust auf der Seite angezeigt wird.
Wechseln Sie zu Visual Studio zurück (ALT+TAB), und drücken Sie die Tastenkombination UMSCHALT+F5, um das Debugging zu beenden.
Nachdem die Funktionsweise der App sichergestellt wurde, können Sie die Speicherauslastung überprüfen.
Analysieren der Speicherauslastung
Wählen Sie auf der Symbolleiste Debuggen in der Liste Debuggen starten das Debugziel für das aktualisierte Projekt aus, entweder die Windows Phone-Emulatoren oder den Simulator.
Tipp
Für eine Windows Store-App können Sie in dieser Liste auch Lokaler Computer oder Remotecomputer auswählen.Allerdings liegt der Vorteil des Emulators oder Simulators darin, dass Sie ihn neben Visual Studio platzieren und problemlos zwischen der laufenden App und der JavaScript-Speicheranalyse wechseln können.Weitere Informationen finden Sie unter Ausführen von Store-Apps aus Visual Studio und Ausführen von Windows Store-Apps auf einem Remotecomputer in Visual Studio.
Wählen Sie im Menü Debuggen die Option Leistung und Diagnose aus.
Wählen Sie unter Verfügbare Tools die Option JavaScript-Memory aus, und wählen Sie dann Starten.
In diesem Lernprogramm fügen Sie die Speicheranalyse an das Startprojekt an. Informationen zu anderen Optionen, wie das Anfügen des Arbeitsspeicheranalyzers an eine installierte App, finden Sie unter Analysieren der Speicherauslastung (JavaScript).
Bei Start des Arbeitsspeicheranalyzers, wird möglicherweise eine Benutzerkontensteuerung die Berechtigung zum Ausführen der Datei "VsEtwCollector.exe" abfragen. Klicken Sie auf Ja.
Wählen Sie viermal nacheinander die Schaltfläche Speicherverlust aus.
Bei Auswahl dieser Schaltfläche funktioniert der Ereignishandlercode in "default.js" so, dass ein Speicherverlust hervorgerufen wird. Dies wird zu Diagnosezwecken verwendet.
Tipp
Durch die Wiederholung des Szenarios, das Sie auf einen Speicherverlust testen möchten, wird es einfacher, irrelevante Informationen herauszufiltern. Dazu zählen beispielsweise Objekte, die dem Heap während des Startens der App oder beim Laden einer Seite hinzugefügt werden.
Wechseln Sie aus der ausgeführten App zu Visual Studio (ALT+TAB).
Die JavaScript-Speicheranalyse zeigt Informationen auf einer neuen Registerkarte in Visual Studio an.
Das Arbeitsspeicherdiagramm in dieser Zusammenfassungsansicht veranschaulicht die Prozessspeicherauslastung im Zeitverlauf. Die Ansicht bietet auch Befehle wie Heap-Momentaufnahme erstellen. Eine Momentaufnahme stellt ausführliche Informationen zur Speicherauslastung zu einem bestimmten Zeitpunkt bereit. Weitere Informationen finden Sie unter Analysieren der Speicherauslastung (JavaScript).
Wählen Sie Heap-Momentaufnahme erstellen aus.
Wechseln Sie zur App, und wählen Sie Speicherverlust aus.
Wechseln Sie zu Visual Studio, und wählen Sie erneut Heap-Momentaufnahme erstellen aus.
Diese Abbildung zeigt die Baselinemomentaufnahme (Nr. 1) und die Momentaufnahme Nr. 2.
Hinweis
Der Windows Phone-Emulator zeigt keinen Screenshot von der App zum Zeitpunkt der Momentaufnahme.
Wechseln Sie zur App, und wählen Sie die Schaltfläche Speicherverlust erneut aus.
Wechseln Sie zu Visual Studio, und wählen Sie zum dritten Mal Heap-Momentaufnahme erstellen aus.
Tipp
Indem eine dritte Momentaufnahme in diesem Workflow aufgenommen wird, können Sie Änderungen zwischen der Baselinemomentaufnahme zur zweiten Momentaufnahme herausfiltern, die mit Arbeitsspeicherverlusten nichts zu tun haben.Es gibt z. B. möglicherweise erwartete Änderungen, wie Aktualisieren von Kopf- und Fußzeilen auf einer Seite, die einige Änderungen bei der Speicherauslastung generiert, aber mit Arbeitsspeicherverlusten nicht in Verbindung steht.
Diese Abbildung zeigt Momentaufnahme Nr. 2 und Momentaufnahme Nr. 3.
Wählen Sie in Visual Studio Beenden aus, um die Profilerstellung zu beenden.
Vergleichen Sie die Momentaufnahmen in Visual Studio. Momentaufnahme 2 zeigt Folgendes:
Die Heapgröße (angezeigt durch den roten Pfeil nach oben auf der linken Seite) hat sich verglichen mit Momentaufnahme Nr. 1 um mehrere KB erhöht.
Wichtig
Die genauen Speicherauslastungswerte für die Heapgröße hängen vom Debugziel ab.
Die Anzahl der Objekte im Heap (angezeigt durch den roten Pfeil nach oben auf der rechten Seite) hat sich verglichen mit Momentaufnahme Nr. 1 erhöht. Ein Objekt wurde hinzugefügt (+ 1), und es wurden keine Objekte entfernt (– 0).
Momentaufnahme 3 zeigt Folgendes:
Die Heapgröße hat sich verglichen mit Momentaufnahme Nr. 2 wieder um mehrere hundert Bytes erhöht.
Die Anzahl der Objekte im Heap hat verglichen mit Momentaufnahme Nr. 2 wieder zugenommen. Ein Objekt wurde hinzugefügt (+ 1), und es wurden keine Objekte entfernt (– 0).
Wählen Sie in Momentaufnahme Nr. 3 den Linktext auf der rechten Seite aus, der einen Wert von +1/-0 neben dem roten Pfeil nach oben anzeigt.
Hierdurch wird die differenzielle Ansicht der Objekte im Heap mit dem Namen Momentaufnahme #3 - Momentaufnahme #2 aufgerufen, bei der die Ansicht "Typen" standardmäßig anzeigt wird. Standardmäßig sehen Sie eine Liste von Objekten, die dem Heap zwischen Momentaufnahme Nr. 2 und Momentaufnahme Nr. 3 hinzugefügt wurden.
Wählen Sie im Filter Bereich die Option Übrige Objekte der Momentaufnahme #2 aus.
Öffnen Sie das HTMLDivElement-Objekt oben in der Objektstruktur wie hier gezeigt.
Diese Ansicht zeigt nützliche Informationen zum Speicherverlust, wie beispielsweise Folgende:
Diese Ansicht zeigt ein DIV-Element mit der ID item. Die beibehaltene Größe für das Objekt beträgt mehrere hundert Bytes (der exakte Wert variiert).
Dieses Objekt ist ein übrig gebliebenes Objekt von Momentaufnahme Nr. 2 und stellt einen potenziellen Speicherverlust dar.
An diesem Punkt sind Kenntnisse der App nützlich: Durch Auswählen der Schaltfläche Speicherverlust sollte ein DIV-Element entfernt sowie ein Element hinzugefügt werden. Der Code scheint also nicht richtig zu funktionieren, d. h. er weist einen Speicherverlust auf. Im nächsten Abschnitt wird beschrieben, wie die behoben werden kann.
Tipp
Manchmal kann das Lokalisieren eines Objekts in Bezug auf das Global-Objekt helfen, das Objekt zu identifizieren.Öffnen Sie hierzu das Kontextmenü für den Bezeichner, und wählen Sie dann In Stammansicht anzeigen aus.
Korrigieren des Arbeitsspeicherproblems
Unter Verwendung von Daten, die der Profiler erkannt hat, untersuchen Sie den Code, durch den DOM-Elemente mit der ID "item" entfernt werden. Dies tritt in der initialize()-Funktion auf.
function initialize() { if (wrapper != null) { elem.removeNode(true); } }
Möglicherweise funktioniert elem.removeNode(true) nicht ordnungsgemäß. Sie untersuchen, wie der Code das DOM-Element zwischenspeichert, und finden ein Problem: Der Verweis auf das zwischengespeicherte Element wird nicht aktualisiert.
Fügen Sie in default.js die folgende Codezeile zur Lastfunktion hinzu, unmittelbar bevor appendChild aufgerufen wird:
elem = newDiv;
Dieser Code aktualisiert den Verweis auf das zwischengespeicherte Element, sodass das Element ordnungsgemäß entfernt wird, wenn Sie die Schaltfläche Speicherverlust auswählen. Der vollständige Code für die Lastfunktion sieht nun wie folgt aus:
function load() { wrapper = document.querySelector(".wrapper"); var newDiv = document.createElement("div"); newDiv.style.zIndex = "-1"; newDiv.id = "item"; elem = newDiv; wrapper.appendChild(newDiv); }
Wählen Sie im Menü Debuggen die Option Leistung und Diagnose aus.
Wählen Sie unter Verfügbare Tools die Option JavaScript-Memory aus, und wählen Sie dann Starten.
Befolgen Sie die gleiche Vorgehensweise wie zuvor, um drei Momentaufnahmen zu erstellen. Die erforderlichen Schritte werden hier zusammengefasst:
Wählen Sie in der App viermal nacheinander die Schaltfläche Speicherverlust aus.
Wechseln Sie zu Visual Studio, und wählen Sie für die Baselinemomentaufnahme Heap-Momentaufnahme erstellen aus.
Wählen Sie in der App die Schaltfläche Speicherverlust aus.
Wechseln Sie zu Visual Studio, und wählen Sie für die zweite Momentaufnahme Heap-Momentaufnahme erstellen aus.
Wählen Sie in der App die Schaltfläche Speicherverlust aus.
Wechseln Sie zu Visual Studio, und wählen Sie für die dritte Momentaufnahme Heap-Momentaufnahme erstellen aus.
Momentaufnahme Nr. 3 zeigt für die Heapgröße jetzt Keine Zunahme seit der Momentaufnahme Nr. 2 an, und der Objektzähler zeigt + 1/– 1 an, womit angegeben wird, dass ein Objekt hinzugefügt und ein Objekt entfernt wurde. Dies ist das gewünschte Verhalten.
Die folgende Abbildung zeigt Momentaufnahme Nr. 2 und Momentaufnahme Nr. 3.