Übung 1.3: Verlustkandidaten analysieren
Bevor Sie mit dieser Übung beginnen, sollten Sie Übung 1.2: Heap-Speicherauszüge erfassen ausgeführt haben.
In dieser Übung werden Sie zunächst eine Liste von Objekten (z. B. von Arrays, Vektoren oder Sitzungen) generieren,
die scheinbar Verluste verursachen. Diese Objekte sind die Verlustkandidaten. Anschließend werden Sie die Liste analysieren, um
vorliegende Lecks festzustellen.
Liste der Verlustkandidaten generieren
Generieren Sie die Liste wie folgt:
- Folgen Sie den Anweisungen in der Ansicht "Verlustkandidaten" und klicken Sie
in der Funktionsleiste auf den Knopf "Auf Verluste analysieren"
. Daraufhin wird das Dialogfenster "Auswahl der Optionen
für Verlustanalyse" geöffnet.
- Vergewissern Sie sich, dass in dem Dialogfenster die Markierungsfelder für die beiden Heap-Speicherauszüge ausgewählt sind.
Anmerkung: Der Schwellenwert ist standardmäßig auf 20 eingestellt. Es werden demzufolge nur Kandidaten mit einer Verlustwahrscheinlichkeit von 20 oder mehr angezeigt. (Weitere Informationen zu Wahrscheinlichkeitswerten finden Sie an späterer Stelle in dieser Übung.)
- Klicken Sie auf OK, um die Liste zu generieren. Der Anzeiger unten rechts auf der Softwareentwicklungsplattform
gibt an, das Verlustkandidaten gefunden wurden.
Ansicht "Verlustkandidaten" im Überblick
Nach Abschluss des Prozesses zeigt die Ansicht "Verlustkandidaten" eine Liste der Verlustkandidaten an.
Jeder Kandidat hat einen Wahrscheinlichkeitswert zwischen 100 und 1, wobei ein Kandidat mit der höchsten Verlustwahrscheinlichkeit einen Wert von 100 hat. Die anderen Kandidaten werden dementsprechend eingestuft und in absteigender Wahrscheinlichkeit aufgelistet. (Der Heap-Vergleichsalgorithmus berechnet die Wahrscheinlichkeitswerte ausgehend von der Größe des Lecks
und der Zunahme des Lecks während des Intervalls zwischen den beiden Heap-Speicherauszügen.)
Für diesen Profilerstellungsdurchgang war der Schwellenwert auf 20 gesetzt.
Alle Kandidaten mit einer Verlustwahrscheinlichkeit von 19 und weniger werden nicht angezeigt.
Für jeden Verlustkandidaten enthält die Ansicht folgende Daten:
- Verlustquelle. Dies ist das Stammobjekt des Ausgangsebene, das Referenzen auf Objekte enthält, die potenziell von einem Verlust betroffen sind.
- Containertyp. Dies ist ein Gruppenobjekt, das die vom Verlust betroffenen Objekte hält. Lecks treten
mit größter Wahrscheinlichkeit in Gruppenobjekten wie Vektoren und Listen auf.
- Wo treten Verluste auf? Dies ist der Typ der vom Verlust betroffenen Objekte.
- Anzahl der Verluste. Dieser Wert repräsentiert die Anzahl der Objekte des in der Spalte "Wo treten Verluste auf?" angegebenen Typs,
die im Containerobjekt enthalten sind. Diese Objekte können wiederum auf andere Objekte verweisen. Diese referenzierten Objekte sind in den Spalten
"Objektverluste" und "Byteverluste" angegeben.
- Byteverluste.
- Objektverluste.
Leck analysieren und identifizieren
Identifizieren Sie das Leck wie folgt:
- Schauen Sie sich in der Ansicht "Verlustkandidaten" die Daten des Kandidaten mit einer Wahrscheinlichkeit von 100 an.
- Die Verlustquelle ist TestThreeTierQueue.<Objekt-ID>.
- Der Containertyp ist vector.
- Im Vektor gibt es Zeichenfolgenverluste. Das heißt, der Vektor hält an Referenzen auf Zeichenfolgen fest,
die er nach der Anzahl der Lecks und der Byteverluste freigeben sollte, damit die Garbage Collection den Speicher bereinigen kann. (Die Anzahl der Lecks und die Höhe der Byteverluste
kann bei jeder Ausführung dieses Programms unterschiedlich sein und hängt von der Zeit ab, zu der die Heap-Speicherauszüge
erfasst werden.)
- Klicken Sie doppelt auf den Verlustkandidaten. Daraufhin wird die Ansicht "Diagramm der Objektreferenzen" geöffnet und zeigt grafische Daten
zum Verlustkandidaten an. (Es kann einige Zeit dauern, bis der Heap-Speicherauszug für die Anzeige aufbereitet ist.)
- Untersuchen Sie das Diagramm der Objektreferenzen. Achten Sie auf die folgenden Punkte:
- Das Diagramm hebt die Objekte hervor, die durch Referenzen
mit dem potenziellen Leck verbunden sind, beginnend bei der Verlustquelle über
die SecondaryQueue zum Vektor und schließlich bis hin zu der vom Verlust betroffenen Gruppe von Zeichenfolgen. Sie haben so eine bildliche Darstellung
des vom Verlust betroffenen Bereichs.
- Im Diagramm gibt es ein Object-Array, auf das ein Vector (der am Leck beteiligte Containertyp) verweist. Das Object-Array wiederum
referenziert vom Verlust betroffene String-Objekte.
- Bewegen Sie den Cursor auf den Pfad zwischen dem Object-Array und dem String-Objekt, um
eine Kurzinfo anzuzeigen. Die Kurzinfo enthält einen "Zähler", der mit der Anzahl
der Verluste in der Ansicht "Verlustkandidaten" übereinstimmt.
Dies ist somit die Zeichenfolgengruppe, die als Leck identifiziert wurde.
- Beachten Sie, dass sowohl die zweite als auch die dritte Warteschlange Referenzen auf
das Object-Array enthalten.
Die dritte Warteschlange ist in der Ansicht "Verlustkandidaten" jedoch nicht als vom
Verlust betroffen angegeben. Hierfür gibt es mehrere mögliche Erklärungen:
- Die dritte Warteschlange kann in der Tat von Verlusten betroffen sein, jedoch in viel geringerem Ausmaß als die zweite (sekundäre) Warteschlange. Wenn Sie die Verlustanalyse erneut ausführen, dieses Mal jedoch mit einem Schwellenwert unter dem Standardwert 20,
sehen Sie unter Umständen, dass für die dritte Warteschlange ein Leck angezeigt wird.
- Es kann gute Gründe geben, aus denen die dritte Warteschlange an den Referenzen auf das Object-Array festhält,
so dass kein Speicherverlust vorliegt, sondern der Speicher nur zurückgehalten wird. Sobald Sie den Code für die sekundäre Warteschlange korrigiert haben und die verbesserte Anwendung erneut ausführen, werden Sie
die genaue Antwort wissen.
- Klicken Sie im Diagramm der Objektreferenzen doppelt auf das Objekt String. Daraufhin wird die Ansicht "Objektdetails" geöffnet. Sie zeigt alle Details zum String-Objekt an sowie alle Objekte, die auf
dieses Objekt verweisen, und alle Objekte, auf die dieses Objekt verweist. In der Ansicht "Objektdetails" können Sie durch die referenzierenden Objekte navigieren, wenn
Sie auf eines
dieser Objekte klicken. Durch die referenzierten Objekte (auf die das Objekt verweist) können Sie navigieren,
wenn Sie auf eines dieser Objekte klicken.
Was haben Sie herausgefunden? Sie wissen jetzt, dass die sekundäre Warteschlange das vom Verlust betroffene Objekt ist und dass
der Verlust auftritt, weil ein Vector-Objekt an Referenzen auf zu viele String-Objekte festhält.
Jetzt können Sie mit Übung 1.4: Speicherverlust korrigieren beginnen.