Messen der Speicherauslastung in Visual Studio (C#, Visual Basic, C++, F#)
Suchen Sie Speicherverluste und ineffiziente Arbeitsspeichernutzung während des Debuggens mit dem im Debugger integrierten Speicherauslastungs-Diagnosetool. Mit dem Speicherauslastungstool können Sie einen oder mehrere Momentaufnahmen des verwalteten und nativen Momentaufnahme-Heaps erstellen, um ein besseres Verständnis darüber zu erlangen, welchen Einfluss die Speicherauslastung von Objekttypen hat. Sie können die Speicherauslastung auch ohne einen angefügten Debugger analysieren, oder indem Sie eine ausgeführte App als Ziel festlegen. Weitere Informationen finden Sie unter Ausführen von Profilerstellungstools mit oder ohne Debugger. Informationen zum Auswählen des für Ihre Anforderungen am besten passenden Speicheranalysetools finden Sie unter Auswählen eines Speicheranalysetools.
Obwohl Sie Speichermomentaufnahmen des Arbeitsspeichers zu jedem beliebigen Zeitpunkt im Speicherauslastungstool erfassen können, können Sie mit dem Visual Studio-Debugger kontrollieren, wie Ihre Anwendung die Ausführung vornimmt, und dabei Leistungsprobleme untersuchen. Festlegen von Haltepunkten, schrittweises Ausführen, alles unterbrechen und andere Debugger-Aktionen können Ihnen helfen, Ihre Leistungsuntersuchungen auf die relevantesten Codepfade zu fokussieren. Durch die Ausführung dieser Aktionen, während Ihre App ausgeführt wird, kann das Rauschen, das Sie nicht interessiert, vom Code entfernt werden, wodurch sich der Zeitaufwand, den Sie zur Diagnose eines Problems benötigen, maßgeblich verringert.
Wichtig
Die in den Debugger integrierten Diagnosetools werden für die .NET-Entwicklung in Visual Studio, darunter ASP.NET, ASP.NET Core, native/C++-Entwicklung sowie für Apps im gemischten Modus (.NET und nativ) unterstützt. Windows 8 und höher ist erforderlich, um die Profilerstellungstools mit dem Debugger auszuführen (Fenster Diagnosetools).
In diesem Tutorial werden Sie Folgendes durchführen:
- Erstellen von Momentaufnahmen des Speichers
- Analysieren der Speicherauslastungsdaten
Wenn Sie von der Speicherauslastung nicht die benötigten Daten erhalten, stehen andere Leistungs-Profiler zur Verfügung, um andere Arten von hilfreichen Informationen zu erhalten. In vielen Fällen kann der Leistungsengpass Ihrer Anwendung durch etwas anderes als den Arbeitsspeicher ausgelöst werden, z.B. durch die CPU, das Rendern der Benutzeroberfläche oder die Anforderungszeit des Netzwerks.
Hinweis
Unterstützung für benutzerdefinierte Speicherbelegungen Der native Speicherprofiler sammelt auf die Speicherbelegung bezogene ETW--Ereignisdaten, die zur Laufzeit ausgegeben werden. Zuweisungen im CRT und Windows SDK wurden auf Quellebene kommentiert, sodass ihre Speicherbelegungsdaten erfasst werden können. Wenn Sie Ihre eigenen Zuweisungen schreiben, kann jede Funktion, die einen Zeiger auf neu zugewiesenen Heapspeicher zurückgibt, mit __declspec(allocator) ergänzt werden, wie in diesem Beispiel für myMalloc zu sehen ist:
__declspec(allocator) void* myMalloc(size_t size)
Sammeln von Speicherauslastungsdaten
Öffnen Sie das Projekt, das Sie in Visual Studio debuggen möchten, und legen Sie in Ihrer App einen Haltepunkt an dem Punkt fest, an dem Sie die CPU-Auslastung untersuchen möchten.
Wenn Sie über einen Bereich verfügen, bei dem Sie ein Speicherproblem vermuten, legen Sie den ersten Haltepunkt fest, bevor das Speicherproblem auftritt.
Tipp
Da es schwierig sein kann, das Speicherprofil eines Vorgangs zu erfassen, der für Sie von Interesse ist, wenn Ihre App häufig Speicher zuweist und dessen Speicherung wieder aufhebt, richten Sie zu Beginn und zum Ende des Vorgangs Haltepunkte ein (oder gehen Sie schrittweise durch den Vorgang), um so den genauen Punkt zu finden, an dem sich der Speicher geändert hat.
Legen Sie einen zweiten Haltepunkt am Ende der Funktion oder des Codebereichs an, den Sie analysieren möchten (oder nachdem ein vermutetes Speicherproblem aufgetreten ist).
Das Fenster Diagnosetools wird automatisch angezeigt, es sei denn, Sie haben es deaktiviert. Klicken Sie auf Debuggen>Windows>Diagnosetools anzeigen, um das Fenster erneut aufzurufen.
Wählen Sie Speicherauslastung mit der Einstellung Auswahltools auf der Symbolleiste aus.
Klicken Sie auf Debuggen / Debugging starten (oder auf Start auf der Symbolleiste oder auf F5).
Wenn das Laden der Anwendung abgeschlossen ist, wird die Zusammenfassungsansicht der Diagnosetools angezeigt.
Hinweis
Da das Erfassen von Speicherdaten die Debugleistung Ihrer systemeigenen Apps oder Ihrer Apps mit gemischtem Modus beeinträchtigen kann, sind Speichermomentaufnahmen standardmäßig deaktiviert. Starten Sie eine Debugsitzung, um Momentaufnahmen in nativen Apps oder in Apps im gemischten Modus zu aktivieren. Nutzen Sie dazu die Tastenkombination F5. Wenn das Fenster Diagnosetools angezeigt wird, wählen Sie die Registerkarte Speicherauslastung und dann Heapprofilerstellung aus.
Beenden Sie den Debugvorgang (Tastenkombination: UMSCHALTTASTE+F5), und starten Sie ihn neu.
Hinweis
Da das Erfassen von Speicherdaten die Debugleistung Ihrer systemeigenen Apps oder Ihrer Apps mit gemischtem Modus beeinträchtigen kann, sind Speichermomentaufnahmen standardmäßig deaktiviert. Starten Sie eine Debugsitzung, um Momentaufnahmen in nativen Apps oder in Apps im gemischten Modus zu aktivieren. Nutzen Sie dazu die Tastenkombination F5. Wenn das Fenster Diagnosetools angezeigt wird, wählen Sie die Registerkarte Speicherauslastung und dann Heapprofilerstellung aus.
Beenden Sie den Debugvorgang (Tastenkombination: UMSCHALTTASTE+F5), und starten Sie ihn neu.
Um eine Momentaufnahme zu Beginn der Debugsitzung zu erstellen, wählen Sie auf der Übersichtssymbolleiste Speicherauslastung die Option Momentaufnahme erstellen aus. (Es kann hilfreich sein, auch hier einen Haltepunkt festzulegen.)
Tipp
Um eine Basislinie für Speichervergleiche zu erstellen, sollten Sie zu Beginn Ihrer Debugsitzung eine Momentaufnahme erstellen.
Führen Sie das Szenario aus, bei dem Ihr erster Haltepunkt erreicht wird.
Wählen Sie Momentaufnahme erstellen auf der Übersichtssymbolleiste Speicherauslastung aus, während der Debugger am ersten Haltepunkt angehalten wird.
Drücken Sie F5, um die App bis zum zweiten Haltepunkt auszuführen.
Erstellen Sie nun eine andere Momentaufnahme.
An diesem Punkt können Sie beginnen, die Daten zu analysieren.
Wenn Probleme beim Sammeln oder Anzeigen von Daten haben, lesen Sie Behandeln von Profilerstellungsfehlern und Beheben von Problemen.
Analysieren der Speicherauslastungsdaten
Die Zeilen der Speicherauslastungs-Übersichtstabelle führen die Momentaufnahmen auf, die Sie während der Debugsitzung erstellt haben, und bieten Links zu detaillierteren Ansichten.
Der Name der Spalte ist abhängig von dem Debugmodus, den Sie in den Projekteigenschaften gewählt haben: .NET, nativ oder gemischt (sowohl .NET als auch nativ).
Die Spalten Objekte (Diff.) und Zuweisungen (Diff.) zeigen die Anzahl der Objekte im .NET-Speicher und im nativen Speicher zum Zeitpunkt der Erstellung der Momentaufnahme an.
Die Spalte Heapgröße (Diff) zeigt die Anzahl der Bytes in den .NET- und nativen Heaps
Wenn Sie mehrere Momentaufnahmen erstellt haben, beinhalten die Zellen der Übersichtstabelle die Wertänderung zwischen Zeilenmomentaufnahme und vorheriger Momentaufnahme.
Um die Speicherauslastung zu analysieren, klicken Sie auf einen der Links. Ein detaillierter Bericht der Speicherauslastung wird geöffnet:
- Um die Details der Unterschiede zwischen aktueller Momentaufnahme und vorheriger Momentaufnahme anzuzeigen, wählen Sie die Änderungsverknüpfung links vom Pfeil aus (
). Ein roter Pfeil zeigt eine Zunahme der Speicherauslastung und ein grüner Pfeil die Abnahme der Speicherauslastung.
Tipp
Um Speicherprobleme schnell auszumachen, werden die Unterschiedsberichte nach Objekttypen sortiert, deren Anzahl sich am stärksten erhöht hat (klicken Sie auf die Änderungsverknüpfung in der Spalte Objekte (Diff.) ) oder deren gesamte Heapgröße sich am signifikantesten erhöht hat (klicken Sie auf die Änderungsverknüpfung in der Spalte Heapgröße (Diff.) ).
Um nur die Details der ausgewählten Momentaufnahme anzuzeigen, klicken Sie auf die Verknüpfung ohne Änderung.
Der Bericht wird in einem separaten Fenster angezeigt.
Berichte zu den verwalteten Typen
Wählen Sie die aktuelle Verknüpfung einer Zelle Objekte (Diff.) oder Zuweisungen (Diff.) in der Übersichtstabelle zur Speicherauslastung aus.
Im oberen Bereich werden Anzahl und Größe der Typen in der Momentaufnahme angezeigt, einschließlich der Größe aller Objekte, auf die der Typ verweist (Umfassende Größe).
Die Baumstruktur Pfade zum Stamm im unteren Bereich zeigt die Objekte an, die auf den im oberen Bereich ausgewählten Typ verweisen. Der .NET-Garbage Collector bereinigt den Speicher für ein Objekt nur, wenn der letzte Typ, der darauf verweist, freigegeben wurde.
Die Baumstruktur Referenzierte Objekte enthält die Verweise, die vom im oberen Bereich ausgewählten Typ gehalten werden.
Die Baumstruktur Referenzierte Typen enthält die Verweise, die von dem Typ, der im oberen Bereich ausgewählt ist, gehalten werden.
Um die Instanzen eines ausgewählten Typs im oberen Bereich anzuzeigen, klicken Sie neben dem Objekttyp auf „Instanzen anzeigen“.
Die Ansicht Instanzen zeigt die Instanzen des ausgewählten Objekts in der Momentaufnahme des oberen Bereichs an. Die Bereiche Pfade zum Stamm und Referenzierte Objekte zeigen die Objekte an, die auf die ausgewählte Instanz verweisen, sowie die Typen, auf die die ausgewählte Instanz verweist. Wenn der Debugger zu dem Zeitpunkt beendet wird, an dem die Momentaufnahme erstellt wurde, können Sie auf die Zelle Wert zeigen, um die Werte des Objekts in einer QuickInfo anzuzeigen.
Berichte zu den systemeigenen Typen
Wählen Sie die aktuelle Verknüpfung einer Zelle Zuweisungen (Diff.) oder Heapgröße (Diff.) aus der Übersichtstabelle zur Speicherauslastung des Fensters Diagnosetools aus.
Die Typenansicht zeigt die Anzahl und Größe der Typen in der Momentaufnahme an.
Wählen Sie das Instanzensymbol (
) eines ausgewählten Typs, um Informationen zu den Objekten des ausgewählten Typs in der Momentaufnahme anzuzeigen.
Die Ansicht Instanzen zeigt jede Instanz des ausgewählten Typs an. Durch Auswahl einer Instanz wird die Aufrufliste angezeigt, welche die Erstellung der Instanz im Bereich Belegungsaufrufliste bewirkt hat.
Wählen Sie Instanzen anzeigen neben einem ausgewählten Typ aus, um Informationen zum Objekt des ausgewählten Typs in der Momentaufnahme anzuzeigen.
Die Ansicht Instanzen zeigt jede Instanz des ausgewählten Typs an. Durch Auswahl einer Instanz wird die Aufrufliste angezeigt, welche die Erstellung der Instanz im Bereich Belegungsaufrufliste bewirkt hat.
Wählen Sie Stapelansicht im Ansichtsmodus , um den Zuweisungsstapel für den ausgewählten Typ anzuzeigen.
Wählen Sie Stapel aus, um den Zuweisungsstapel für den ausgewählten Typ anzuzeigen.
Erkenntnisse zur Speicherauslastung
Für verwalteten Speicher bietet das Speicheranalysetool auch mehrere leistungsstarke integrierte automatische Erkenntnisse. Wählen Sie die Registerkarte Erkenntnisse in den Berichten vom Typ „Verwaltet“ aus, um die anwendbaren automatischen Erkenntnisse anzuzeigen, z. B. Doppelte Zeichenfolgen, spärliche Arrays und Ereignishandlerverluste.
Im Abschnitt Doppelte Zeichenfolgen wird die Liste der Zeichenfolgen angezeigt, die mehrmals auf dem Heap zugeordnet werden. Darüber hinaus wird in diesem Abschnitt der gesamtverwendete Arbeitsspeicher angezeigt, d. h. die (Anzahl der Instanzen -1)-mal so groß wie die Zeichenfolge.
Der Abschnitt Sparse-Arrays zeigt Arrays, die größtenteils mit Nullelementen gefüllt sind, was in Bezug auf Leistung und Speicherauslastung ineffizient sein kann. Das Speicheranalysetool erkennt diese Arrays automatisch und zeigt Ihnen an, wie viel Arbeitsspeicher aufgrund dieser Nullwerte verschwendet wird.
Im Abschnitt Ereignishandlerverluste, der in Visual Studio 2022, Version 17.9 Preview 1 verfügbar ist, werden potenzielle Arbeitsspeicherverluste angezeigt, die auftreten können, wenn ein Objekt das Ereignis eines anderen Objekts abonniert. Wenn der Herausgeber des Ereignisses den Abonnenten überdauert, bleibt der Abonnent bestehen, auch wenn es keine weiteren Verweise auf ihn gibt. Dies kann zu Speicherverlusten führen, bei denen nicht verwendeter Arbeitsspeicher nicht ordnungsgemäß freigegeben wird, was dazu führt, dass die Anwendung im Laufe der Zeit mehr und mehr Arbeitsspeicher verwendet.
Für bestimmte Typen sind Felder bekannt, die gelesen werden können, um die Größe des nativen Speichers zu bestimmen, an dem sie sich befinden. Auf der Registerkarte Insights werden gefälschte native Speicherknoten im Objektdiagramm angezeigt, die von ihren übergeordneten Objekten aufbewahrt werden, sodass die Benutzeroberfläche sie erkennt und ihre Größe und ihr Verweisdiagramm anzeigt.
(Diff) Änderungsberichte
Wählen Sie die Änderungsverknüpfung in einer Zelle der Übersichtstabelle der Registerkarte Speicherauslastung im Fenster Diagnosetools aus.
Wählen Sie eine Momentaufnahme aus der Liste Vergleichen mit Liste eines verwalteten oder systemeigenen Berichts aus.
Der Änderungsbericht fügt dem Basisbericht Spalten (durch (Diff) gekennzeichnet) hinzu, die den Unterschied zwischen der Basismomentaufnahme und der Vergleichsmomentaufnahme anzeigen. So könnte ein Unterschiedsbericht der Ansicht mit nativen Typen aussehen:
Blogs und Videos
Analyze CPU and Memory While Debugging (Analysieren der CPU und des Arbeitsspeichers beim Debuggen)
Nächste Schritte
In diesem Tutorial haben Sie gelernt, wie Speicherauslastungsdaten gesammelt und analysiert werden. Wenn Sie die Einführung in Profiler bereits abgeschlossen haben, sollten Sie sich über einen allgemeinen Ansatz zur Optimierung von Code mithilfe der Profilerstellungstools informieren.
In diesem Tutorial haben Sie gelernt, wie Speicherauslastungsdaten beim Debuggen gesammelt und analysiert werden. Mehr über die Analyse der Arbeitsspeicherauslastung in Releasebuilds erfahren Sie mithilfe des Leistungs-Profilers.