Freigeben über


Messen der Speicherauslastung in Visual Studio (C#, Visual Basic, C++, F#)

Suchen Sie Speicherverluste und ineffizienten Arbeitsspeicher, während Sie mit dem debuggerintegrierten Speicherauslastung-Diagnosetool debuggen. 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 Speichernutzung auch ohne angefügten Debugger analysieren oder auf eine ausgeführte App abzielen. Weitere Informationen finden Sie unter Ausführen von Profilerstellungstools für Release- oder Debugbuilds. Informationen zum Auswählen des besten Speicheranalysetools für Ihre Anforderungen finden Sie unter Auswählen eines Speicheranalysetools.

Sie können speichermomentaufnahmen zwar jederzeit im Memory Usage Tool sammeln, Sie können jedoch den Visual Studio Debugger verwenden, um zu steuern, wie Ihre Anwendung ausgeführt wird, während Sie 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. Das Ausführen dieser Aktionen während der Ausführung der App kann das Rauschen aus dem Code beseitigen, der Sie nicht interessiert, und die Zeit, die Sie zum Diagnostizieren eines Problems benötigt, erheblich reduzieren.

Tipp

Sie können auch den GitHub Copilot Profiler Agent verwenden, um KI-gesteuerte Anleitungen zum Sammeln und Analysieren von Speicherablaufverfolgungen zu erhalten.

Wichtig

Die debuggerintegrativen Diagnosetools werden für .NET Entwicklung in Visual Studio unterstützt, einschließlich ASP.NET, ASP.NET Core, native/C++-Entwicklung und gemischten Apps (.NET und systemeigener Modus).

In diesem Tutorial werden Sie folgendes tun:

  • Momentaufnahmen des Arbeitsspeichers erstellen
  • Analysieren von Speichernutzungsdaten

Wenn Speicherauslastung Ihnen nicht die benötigten Daten liefert, stellen andere Profilerstellungstools im Performance Profiler verschiedene Arten von Informationen bereit, die Ihnen möglicherweise hilfreich sind. In vielen Fällen kann der Leistungsengpass Ihrer Anwendung durch etwas anderes als Ihren Speicher verursacht werden, z. B. die CPU, das UI-Rendering oder die Netzwerkanfragenzeit.

Anmerkung

Unterstützung für benutzerdefinierte Speicherbelegungen Der native Speicherprofiler sammelt auf die Speicherbelegung bezogene ETW--Ereignisdaten, die zur Laufzeit ausgegeben werden. Allocatoren im CRT- und Windows-SDK wurden auf Quellcode-Ebene annotiert, sodass ihre Zuordnungsdaten 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

  1. Öffnen Sie die project, die Sie in Visual Studio debuggen möchten, und legen Sie an der Stelle, an der Sie mit der Überprüfung der Speicherauslastung beginnen möchten, einen Haltepunkt in Ihrer App fest.

    Wenn Sie einen Bereich haben, in 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 Sie interessiert, wenn Ihre App häufig Speicher zuweist und den Speicher de-ordnet, legen Sie Haltepunkte am Anfang und Ende des Vorgangs fest (oder durchlaufen Sie den Vorgang), um den genauen Punkt zu finden, an dem sich der Speicher geändert hat.

  2. Legen Sie einen zweiten Haltepunkt am Ende der Funktion oder des Codes fest, die Sie analysieren möchten (oder nachdem ein verdächtiges Speicherproblem auftritt).

  3. Das Fenster Diagnosetools wird automatisch angezeigt, es sei denn, Sie haben es deaktiviert. Um das Fenster erneut anzuzeigen, klicken Sie auf DebuggenWindowsDiagnosetools anzeigen.

  4. Wählen Sie Speicherauslastung mit der Einstellung Auswahltools auf der Symbolleiste aus.

    Screenshot des Fensters "Diagnosetools", in dem das Speichernutzungstool im Dropdown-Menü "Tools auswählen" ausgewählt ist.

    Screenshot des Fensters "Diagnosetools", in dem das Speichernutzungstool im Dropdown-Menü "Tools auswählen" ausgewählt ist.

  5. Klicken Sie auf Debuggen / Debugging starten (oder auf Start auf der Symbolleiste oder auf F5).

    Nach Abschluss des Ladens der App wird die Zusammenfassungsansicht der Diagnosetools angezeigt.

    Screenshot der Registerkarte "Übersicht der Diagnosetools" mit dem Zeitdiagramm zur "Speicherauslastung" und dem "Prozessspeicherdiagramm".

    Anmerkung

    Da das Erfassen von Speicherdaten die Debugleistung Ihrer systemeigenen Apps oder Ihrer Apps mit gemischtem Modus beeinträchtigen kann, sind Speichermomentaufnahmen standardmäßig deaktiviert. Um Momentaufnahmen in systemeigenen oder gemischten Apps zu aktivieren, starten Sie eine Debugsitzung (Tastenkombination: F5). Wenn das Fenster Diagnosetools angezeigt wird, wählen Sie die Registerkarte Speicherauslastung und dann Heap-Profilerstellungaus.

    Screenshot der Symbolleiste "Speichernutzung" mit hervorgehobener Schaltfläche "Heap-Profiling", um Momentaufnahmen für native oder gemischte Apps zu erstellen.

    Beenden (Tastenkombination: UmschalttasteF5) und Debuggen neu starten.

    Screenshot der Registerkarte "Übersicht der Diagnosetools" mit dem Zeitdiagramm zur "Speicherauslastung" und dem "Prozessspeicherdiagramm".

    Anmerkung

    Da das Erfassen von Speicherdaten die Debugleistung Ihrer systemeigenen Apps oder Ihrer Apps mit gemischtem Modus beeinträchtigen kann, sind Speichermomentaufnahmen standardmäßig deaktiviert. Um Momentaufnahmen in systemeigenen oder gemischten Apps zu aktivieren, starten Sie eine Debugsitzung (Tastenkombination: F5). Wenn das Fenster Diagnosetools angezeigt wird, wählen Sie die Registerkarte Speicherauslastung und dann Heap-Profilerstellungaus.

    Screenshot der Symbolleiste "Speichernutzung" mit hervorgehobener Schaltfläche "Heap-Profiling", um Momentaufnahmen für native oder gemischte Apps zu erstellen.

    Beenden (Tastenkombination: UmschalttasteF5) und Debuggen neu starten.

  6. Um eine Momentaufnahme zu Beginn der Debugsitzung zu erstellen, wählen Sie auf der Übersichtssymbolleiste Speicherauslastung die Option Momentaufnahme erstellen aus. (Es kann auch hilfreich sein, einen Haltepunkt hier festzulegen.)

    Screenshot der Zusammenfassungssymbolleiste "Speicherauslastung" mit der Schaltfläche "Momentaufnahme erstellen".

    Tipp

    Um einen Basisplan für Speichervergleiche zu erstellen, sollten Sie am Anfang der Debugsitzung eine Momentaufnahme erstellen.

  7. Führen Sie das Szenario aus, bei dem Ihr erster Haltepunkt erreicht wird.

  8. Während der Debugger am ersten Haltepunkt angehalten ist, wählen Sie im Zusammenfassungswerkzeug Speicherauslastung die Option Momentaufnahme erstellen aus.

  9. Drücken Sie F5, um die App bis zum zweiten Haltepunkt auszuführen.

  10. Erstellen Sie nun eine weitere Momentaufnahme.

An diesem Punkt können Sie mit der Analyse der Daten beginnen.

Wenn Sie Probleme beim Sammeln oder Anzeigen von Daten haben, lesen Sie Behandeln von Profilerstellungsfehlern und Beheben von Problemen.

Analysieren von Speichernutzungsdaten

Die Zeilen der Speicherauslastungs-Übersichtstabelle führen die Momentaufnahmen auf, die Sie während der Debugsitzung erstellt haben, und bieten Links zu detaillierteren Ansichten.

Screenshot der Zusammenfassungstabelle "Speicherauslastung" mit zwei Momentaufnahmen mit Spalten für Objekte, Heapgröße und deren Unterschiede.

Der Name der Spalte hängt von dem Debugmodus ab, den Sie in den Projekteigenschaften auswählen: .NET, native oder gemischt (sowohl .NET als auch native).

  • Die Spalte Objects (Diff) (.NET) oder Allocations (Diff) (C++) zeigt die Anzahl der Objekte in .NET oder systemeigenem Speicher an, wenn die Momentaufnahme erstellt wurde.

  • Die Spalte Heap Size (Diff) zeigt die Anzahl der Bytes in den .NET- und nativen Heaps an.

Wenn Sie mehrere Momentaufnahmen erstellt haben, enthalten die Zellen der Zusammenfassungstabelle die Änderung des Werts zwischen der Zeilenmomentaufnahme und der vorherigen Momentaufnahme.

Um die Speicherauslastung zu analysieren, klicken Sie auf einen der Links, über die ein detaillierter Bericht über die Speicherauslastung geöffnet wird:

  • Um Details des Unterschieds zwischen der aktuellen Momentaufnahme und der vorherigen Momentaufnahme anzuzeigen, wählen Sie den Änderungslink links neben dem Pfeil aus (ArbeitsspeicherauslastungssteigerungArbeitsspeicherauslastung erhöhen). Ein roter Pfeil zeigt eine Erhöhung der Speicherauslastung an, und ein grüner Pfeil zeigt eine Abnahme an.

Tipp

Um Speicherprobleme schneller zu identifizieren, werden die Diff-Berichte nach Objekttypen sortiert, die sich in der Gesamtanzahl am meisten erhöht haben (klicken Sie auf den Änderungslink in der Spalte Objekte (Diff)), oder die, in der sich die Gesamtheapgröße am meisten erhöht hat (klicken Sie auf den Änderungslink in der Spalte Heap-Größe (Diff)).

  • Um Details nur der ausgewählten Momentaufnahme anzuzeigen, klicken Sie auf den Link ohne Änderungen.

    Der Bericht wird in einem separaten Fenster angezeigt.

Berichte zu den verwalteten Typen

Wählen Sie den aktuellen Link einer Objects (Diff) Zelle in der Zusammenfassungstabelle "Speicherauslastung" aus.

Screenshot: Bericht zu verwalteten Typen.Bericht zu verwalteten Typen

Anmerkung

Für .NET-Code ist das View Details-Symbol (Das Instanzsymbol in der Spalte ) nur verfügbar, wenn Sie das Debugging-integrierte Tool zur Speicherauslastung verwenden oder wenn Sie einen Heap-Snapshot öffnen und Debug Managed Memory auswählen.

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 (Inklusive 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. Weitere Informationen zur Verwendung der Pfade zum Stamm--Struktur finden Sie unter Analysieren des langsamsten Pfads zum Stamm.

Screenshot: Bericht zu verwalteten Typen.Bericht zu verwalteten Typen

Anmerkung

Für .NET-Code ist das View Instances-Symbol (das Instanzsymbol in der Spalte ) nur verfügbar, wenn Sie das Tool Debugger-Integrated Memory Usage verwenden oder wenn Sie einen Heap-Snapshot öffnen und Debug Managed Memory auswählen.

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 (Inklusive 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. Weitere Informationen zur Verwendung der Pfade zum Stamm--Struktur finden Sie unter Analysieren des langsamsten Pfads zum Stamm.

Die Baumstruktur Referenzierte Typen enthält die Verweise, die von dem Typ, der im oberen Bereich ausgewählt ist, gehalten werden.

Screenshot des Berichts "Referenzierte Objekte".

Die Baumstruktur Referenzierte Typen enthält die Verweise, die von dem Typ, der im oberen Bereich ausgewählt ist, gehalten werden.

Screenshot des Berichts "Referenzierte Objekte".

Um die Instanzen eines ausgewählten Typs im oberen Bereich anzuzeigen, klicken Sie neben dem Objekttyp auf das Symbol " Details anzeigen ".

Screenshot: Ansicht „Instanzen“ im Speichernutzungstool.Ansicht „Instanzen“ im Speichernutzungstool

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.

Um die Instanzen eines ausgewählten Typs im oberen Bereich anzuzeigen, klicken Sie neben dem Objekttyp auf das Symbol Instanzen anzeigen.

Screenshot: Ansicht „Instanzen“ im Speichernutzungstool.Ansicht „Instanzen“ im Speichernutzungstool

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 nativen Typen

Wählen Sie die aktuelle Verknüpfung einer Zuweisungen (Diff.)- oder Heapgröße (Diff.)-Zelle aus der Zusammenfassungstabelle zur Speicherauslastung im Fenster Diagnosetools aus.

Screenshot: Ansicht „Nativer Typ“.

Screenshot: Ansicht „Nativer Typ“.

Die Typenansicht zeigt die Anzahl und Größe der Typen in der Momentaufnahme an.

  • Wählen Sie das Symbol "Details anzeigen" neben einem ausgewählten Typ aus, 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. (Diese Informationen sind nur beim Debuggen verfügbar.)

    Screenshot: Ansicht „Instanzen“ und Bereich „Belegungsaufrufliste“.

  • Wählen Sie das Symbol Instanzen anzeigen neben einem ausgewählten Typ aus, 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. (Diese Informationen sind nur beim Debuggen verfügbar.)

    Screenshot: Ansicht „Instanzen“ und Bereich „Belegungsaufrufliste“.

  • Wählen Sie Stack aus, um den Zuordnungsstack für den ausgewählten Typ anzuzeigen.

    Screenshot der Stapelansicht.

  • Wählen Sie Stack aus, um den Zuordnungsstack für den ausgewählten Typ anzuzeigen.

    Screenshot der Stapelansicht.

Einblicke zur Speicherauslastung

Für verwalteten Speicher bietet das Speicheranalysetool auch mehrere integrierte leistungsstarke 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, Sparsearrays und Ereignishandlerverluste.

Screenshot der Übersicht im Tool "Speichernutzung".Speicherauslastung-Übersicht

Screenshot der Übersicht im Tool "Speichernutzung".Speicherauslastung-Übersicht

Im Abschnitt duplizierte Zeichenfolgen wird die Liste der Zeichenfolgen angezeigt, die mehrmals auf dem Heap zugeordnet werden. Darüber hinaus zeigt dieser Abschnitt den gesamten verschwendeten Arbeitsspeicher, d. h. die (Anzahl der Instanzen - 1) mal die Größe der Zeichenfolge.

Der Abschnitt Sparse Arrays zeigt Arrays an, die hauptsächlich mit Nullelementen gefüllt sind, was ineffizient in Bezug auf Leistung und Speicherauslastung sein kann. Das Speicheranalysetool erkennt diese Arrays automatisch und zeigt Ihnen, wie viel Arbeitsspeicher aufgrund dieser Nullwerte verschwendet wird.

Der Abschnitt Event Handler Leaks, verfügbar in Visual Studio 2022, Version 17.9 Preview 1, zeigt potenzielle Speicherverluste an, die auftreten können, wenn ein Objekt das Ereignis eines anderen Objekts abonniert. Wenn der publisher des Ereignisses den Abonnent überlebt, bleibt der Abonnent lebendig, auch wenn keine anderen Verweise darauf vorhanden sind. Dies kann zu Speicherlecks 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, zu dem sie gehören. Auf dem Tab Insights werden gefälschte native Speicher-Knoten im Objektdiagramm angezeigt, die von ihren übergeordneten Objekten beibehalten werden, sodass die Benutzeroberfläche sie erkennt und ihre Größe sowie die Referenzstruktur anzeigt.

Screenshot der nativen Ansicht zu Erkenntnissen im Speicherauslastungstool.Native Ansicht zu Erkenntnissen im Speicherauslastungstool

(Diff) Änderungsberichte

  • Wählen Sie den Änderungslink in einer Zelle der Zusammenfassungstabelle der Registerkarte Speicherauslastung im Fenster Diagnosetools aus.

    Screenshot der Zusammenfassungstabelle "Speichernutzung" mit hervorgehobenem Link "Änderung" in einer Momentaufnahmezelle.

  • Wählen Sie eine Momentaufnahme aus der Liste Vergleichen mit Liste eines verwalteten oder systemeigenen Berichts aus.

    Screenshot der Dropdownliste "Vergleichen mit" in einem Bericht zur Speicherauslastung mit verfügbaren Momentaufnahmen für den Vergleich.

    Screenshot der Dropdownliste "Vergleichen mit" in einem Bericht zur Speicherauslastung mit verfügbaren Momentaufnahmen für den Vergleich.

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 für die Ansicht mit nativen Typen aussehen:

Screenshot: Ansicht „Unterschiede bei nativen Typen“Ansicht „Unterschiede bei nativen Typen“

Screenshot: Ansicht „Unterschiede bei nativen Typen“Ansicht „Unterschiede bei nativen Typen“

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 (Inklusive Größe).

Blogs und Videos

Analysieren Sie die CPU und den Arbeitsspeicher beim Debuggen

Visual C++-Blog: Speicherprofilerstellung in Visual C++ 2015

Nächste Schritte

In diesem Lernprogramm haben Sie gelernt, wie Sie Beim Debuggen Speichernutzungsdaten sammeln und analysieren. Hier sind einige vorgeschlagene nächste Schritte:

  • Informationen zum Analysieren der Speicherauslastung in Releasebuilds finden Sie unter Analysieren der Speicherauslastung im Performance Profiler.
  • Eine allgemeine Vorgehensweise zur Optimierung von Code mithilfe der Profilerstellungstools finden Sie in der Fallstudie: Leitfaden für Anfänger zur Optimierung von Code.
  • Um KI-gesteuerte Profilerstellungshilfen zu erhalten, siehe Profile Ihre App mit GitHub Copilot Profiler Agent.
  • Eine Übersicht über alle Profilerstellungstools finden Sie unter "Erste Übersicht über Profilerstellungstools".