Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel gilt für: ✔️ dotnet-dump 3.0.47001 und höhere Versionen
Hinweis
dotnet-dump für macOS wird nur mit .NET 5 und höheren Versionen unterstützt.
Installieren
Es gibt zwei Möglichkeiten, dotnet-dump herunterzuladen und zu installieren:
dotnet-Globaltool:
Verwenden Sie zum Installieren der neuesten Veröffentlichungsversion des
dotnet-dumpNuGet-Pakets den Befehl dotnet tool install:dotnet tool install --global dotnet-dumpDirekter Download:
Laden Sie die ausführbare Datei für das Tool herunter, die Ihrer Plattform entspricht:
Betriebssystem Plattform Windows x86 | x64 | Arm | Arm-x64 Linux (Englisch) x64 | Arm | Arm64 | musl-x64 | musl-Arm64
Hinweis
Sie benötigen eine entsprechende x86-Version des Tools, um dotnet-dump für eine x86-App verwenden zu können.
Übersicht
dotnet-dump [-h|--help] [--version] <command>
Beschreibung
Das globale Tool dotnet-dump ist eine Möglichkeit zum Sammeln und Analysieren von Dumps auf Windows, Linux und macOS ohne systemeigene Debugger. Dieses Tool ist auf Plattformen wie z. B. Alpine Linux wichtig, bei denen kein voll funktionsfähiges Tool lldb verfügbar ist. Mit dem Tool dotnet-dump können Sie SOS-Befehle zum Analysieren von Abstürzen und dem Garbage Collector (GC) ausführen, es handelt sich jedoch nicht um einen nativen Debugger, sodass Elemente wie das Anzeigen von nativen Stapelrahmen nicht unterstützt werden.
Optionen
--versionMit dieser Option wird die Version des Hilfsprogramms „dotnet-dump“ angezeigt.
-h|--helpZeigt die Hilfe für die Befehlszeile an.
Befehle
| Befehl |
|---|
| dotnet-dump collect |
| dotnet-dump analyse |
| dotnet-dump ps |
dotnet-dump collect
Erfasst ein Speicherabbild von einem Prozess.
Übersicht
dotnet-dump collect [-h|--help] [-p|--process-id] [-n|--name] [--type] [-o|--output] [--diag] [--crashreport]
Optionen
-h|--helpZeigt die Hilfe für die Befehlszeile an.
-p|--process-id <PID>Hiermit wird die ID-Nummer des Prozesses angegeben, von dem ein Speicherabbild gesammelt werden soll.
-n|--name <name>Hiermit wird der Name des Prozesses angegeben, von dem ein Speicherabbild gesammelt werden soll.
--type <Full|Heap|Mini>Gibt den Speicherabbildtyp an, der festlegt, welche Arten von Informationen vom Prozess gesammelt werden. Es gibt drei Typen:
-
Full: Das größte Speicherabbild, das den gesamten Arbeitsspeicher einschließlich der Modulimages enthält -
Heap: eine große und relativ umfassende Sicherung, die Modullisten, Threadlisten, alle Stapel, Ausnahmeinformationen, Handleinformationen und den gesamten Arbeitsspeicher mit Ausnahme von zugeordneten Images enthält. -
Mini: eine kleine Sicherung, die Modullisten, Threadlisten, Ausnahmeinformationen und alle Stapel enthält. -
Triage– Ein kleines Dump mit Modullisten, Threadlisten, Ausnahmeinformationen, allen Stapeln und PII entfernt.
Wenn nichts anderes angegeben wird, wird als Standard
Fullverwendet.-
-o|--output <output_dump_path>Der vollständige Pfad und der Dateiname, in den das gesammelte Speicherabbild geschrieben werden soll. Stellen Sie sicher, dass der Benutzer, unter dem der DotNet-Prozess ausgeführt wird, über Schreibberechtigungen für das angegebene Verzeichnis verfügt.
Wenn nichts angegeben wird, gilt:
- Der Standardwert ist .\dump_YYYYMMDD_HHMMSS.dmp für Windows.
- Unter Linux und macOS ist der Standard ./core_JJJJMMTT_HHMMSS.
JJJJMMTT entspricht Jahr/Monat/Tag, und HHMMSS entspricht Stunde/Minute/Sekunde.
--diagAktiviert die Diagnoseprotokollierung für die Speicherabbildsammlung.
--crashreportAktiviert die Absturzberichtsgenerierung.
Hinweis
Unter Linux und macOS erwartet dieser Befehl, dass die Zielanwendung und dotnet-dump die gleiche TMPDIR-Umgebungsvariable verwenden. Andernfalls führt der Befehl zu einem Timeout.
Hinweis
Wenn Sie mit dotnet-dump ein Speicherabbild erfassen möchten, muss der Befehl vom Rootbenutzer oder dem Benutzer ausgeführt werden, der den Zielprozess ausführt. Andernfalls kann das Tool keine Verbindung mit dem Zielprozess herstellen.
Hinweis
Das Sammeln eines vollständigen Oder Heap-Dumps kann dazu führen, dass das Betriebssystem im wesentlichen virtuellen Speicher für den Zielprozess ausgelagert wird. Wenn der Zielprozess in einem Container mit einem erzwungenen Speicherlimit ausgeführt wird, kann die erhöhte Speicherauslastung dazu führen, dass das Betriebssystem den Container beendet, wenn der Grenzwert überschritten wurde. Es wird empfohlen, tests durchzuführen, um sicherzustellen, dass der Speichergrenzwert hoch genug ist. Eine weitere Option besteht darin, den Grenzwert vor der Dumpsammlung vorübergehend zu ändern oder zu entfernen, wenn Ihre Umgebung dies unterstützt.
dotnet-dump analyse
Startet eine interaktive Shell zum Durchsuchen eines Speicherabbilds. Die Shell akzeptiert verschiedene SOS-Befehle.
Übersicht
dotnet-dump analyze <dump_path> [-h|--help] [-c|--command]
Argumente
<dump_path>Gibt den Pfad zu der Speicherabbilddatei an, die analysiert werden soll.
Optionen
-c|--command <debug_command>Führt den Befehl beim Start aus. Mehrere Instanzen dieses Parameters können in einem Aufruf zum Verketten von Befehlen verwendet werden. Befehle werden in der Reihenfolge ausgeführt, in der sie in der Befehlszeile bereitgestellt werden. Wenn „dotnet dump“ nach den Befehlen beendet werden soll, muss der letzte Befehl „exit“ lauten.
SOS-Befehle zum Analysieren
| Befehl | Funktion |
|---|---|
analyzeoom |
Zeigt Informationen zum letzten OOM-Ereignis an, das bei einer Speicherbelegungsanforderung an den Garbage Collection-Heap aufgetreten ist. |
clrmodules |
Listet die verwalteten Module im Prozess auf. |
clrstack |
Stellt eine Stapelüberwachung ausschließlich für verwalteten Code bereit. |
clrthreads |
Listet die verwalteten Threads auf, die ausgeführt werden. |
clru |
Zeigt eine mit Anmerkungen versehene Disassembly einer verwalteten Methode an. |
d oder readmemory |
Sichert Arbeitsspeicherinhalte. |
dbgout |
Aktiviert/deaktiviert (-off) die interne SOS-Protokollierung. |
dso |
Zeigt alle innerhalb der Grenzen des aktuellen Stapels gefundenen verwalteten Objekte an. |
dumpalc |
Zeigt Details zu einem entladbaren AssemblyLoadContext an, in den das angegebene Objekt geladen wird. |
dumparray |
Zeigt Details zu einem verwalteten Array an. |
dumpasync |
Zeigt Informationen zu Computern im asynchronen Status im Heap der Garbage Collection an. |
dumpassembly |
Zeigt Details zu einer Assembly an. |
dumpclass |
Zeigt Informationen zur EEClass-Struktur bei der angegebenen Adresse an. |
dumpconcurrentdictionary |
Zeigt parallele Wörterbuchinhalte an. |
dumpconcurrentqueue |
Zeigt parallele Warteschlangeninhalte an. |
dumpdelegate |
Zeigt Informationen zu einem Delegaten an. |
dumpdomain |
Zeigt Informationen zu allen Assemblys in allen Anwendungsdomänen oder in der angegebenen Domäne an. |
dumpgcdata |
Zeigt Informationen zu Garbage Collection-Daten an. |
dumpgen |
Zeigt den Heapinhalt für die angegebene Generation an. |
dumpheap |
Zeigt Informationen zum Garbage Collector-Heap und Sammlungsstatistiken zu Objekten an. |
dumpil |
Zeigt die allgemeine Zwischensprache (CIL) an, die einer verwalteten Methode zugeordnet ist. |
dumplog |
Schreibt den Inhalt eines Belastungsprotokolls im Speicher in die angegebene Datei. |
dumpmd |
Zeigt Informationen zur MethodDesc-Struktur bei der angegebenen Adresse an. |
dumpmodule |
Zeigt Informationen zum Modul bei der angegebenen Adresse an. |
dumpmt |
Zeigt Informationen zur Methodentabelle bei der angegebenen Adresse an. |
dumpobj |
Zeigt Informationen zum Objekt bei der angegebenen Adresse an. |
dumpruntimetypes |
Sucht alle System.RuntimeType-Objekte im Garbage Collection-Heap und gibt den Typnamen und die MethodTable aus, auf die sie verweisen. |
dumpsig |
Sichert die Signatur einer Methode oder eines Felds, die bzw. das durch <sigaddr> <moduleaddr> angegeben wird. |
dumpsigelem |
Sichert ein einzelnes Element eines Signaturobjekts. |
dumpstackobjects |
Zeigt alle innerhalb der Grenzen des aktuellen Stapels gefundenen verwalteten Objekte an. |
dumpvc |
Zeigt Informationen zu den Feldern einer Wertklasse an. |
eeheap |
Zeigt Informationen zu dem von internen Laufzeit-Datenstrukturen verwendeten Prozessspeicher an. |
eestack |
Führt dumpstack für alle Threads im Prozess aus. |
eeversion |
Zeigt Informationen zu den Runtime- und SOS-Versionen an. |
ehinfo |
Zeigt die Ausnahmebehandlungsblöcke in einer angegebenen JIT-Methode an. |
exit oder quit |
Beendet den interaktiven Modus. |
finalizequeue |
Zeigt alle für den Abschluss registrierten Objekte an. |
findappdomain |
Versucht, die Anwendungsdomäne eines Garbage Collection-Objekts aufzulösen. |
gchandles |
Zeigt Statistiken über Garbage Collector-Handles im Prozess an. |
gcheapstat |
Zeigt Statistiken zum Garbage Collector an. |
gcinfo |
Zeigt die JIT-Garbage Collection-Codierung für eine Methode an. |
gcroot |
Zeigt Informationen zu Verweisen auf das Objekt (oder Stämmen) bei der angegebenen Adresse an. |
gcwhere |
Zeigt den Speicherort im Garbage Collection-Heap der angegebenen Adresse an. |
histclear |
Gibt alle von der Familie der Hist-Befehle verwendeten Ressourcen frei. |
histinit |
Initialisiert die SOS-Strukturen aus dem Belastungsprotokoll, die in der zu debuggenden Komponente gespeichert sind. |
histobj |
Untersucht alle Aufzeichnungen von Belastungsprotokollumsetzungen und zeigt die Kette von Garbage Collection-Umsetzungen an, die möglicherweise zu der als Argument übergebenen Adresse geführt haben. |
histobjfind |
Zeigt alle Protokolleinträge an, die auf das Objekt bei der angegebenen Adresse verweisen. |
histroot |
Zeigt Informationen zu sowohl Heraufstufungen als auch Umsetzungen des angegebenen Stamms an. |
histstats |
Zeigt Statistiken zum Belastungsprotokoll an. |
ip2md |
Zeigt die MethodDesc-Struktur bei der angegebenen Adresse in JIT (Just-In-Time)-kompiliertem Code an. |
listnearobj |
Zeigt das Objekt an, das der angegebenen Adresse vorausgeht und darauf folgt. |
logopen |
Aktiviert die Protokollierung der Konsolendatei. |
logclose |
Deaktiviert die Protokollierung der Konsolendatei. |
logging |
Aktiviert/deaktiviert die interne SOS-Protokollierung. |
lm oder modules |
Zeigt die nativen Module im Prozess an. |
name2ee |
Zeigt die Strukturen MethodTable und EEClass für den angegebenen Typ oder die angegebene Methode im angegebenen Modul an. |
objsize |
Zeigt die Größe des angegebenen Objekts an. |
parallelstacks |
Zeigt den zusammengeführten Threads-Stapel ähnlich wie im Visual Studio Bereich "Parallele Stapel" an. |
pathto |
Zeigt den Garbage Collection-Pfad von <root> zu <target> an. |
pe oder printexception |
Zeigt die Felder jedes Objekts an, das bei der angegebenen Adresse von der Exception-Klasse abgeleitet wird, und formatiert diese Felder. |
r oder registers |
Zeigt die Register des Threads an. |
runtimes |
Listet die Runtimes im Ziel auf oder ändert die Standardruntime. |
setclrpath |
Legt den Pfad zum Laden von CoreCLR-DAC/DBI-Dateien mithilfe von setclrpath <path> fest. |
setsymbolserver |
Aktiviert Unterstützung für den Symbolserver. |
sos |
Führt verschiedene CoreCLR-Debugbefehle aus. Verwenden Sie die Syntax sos <command-name> <args>. Weitere Informationen finden Sie unter „soshelp“. |
soshelp oder help |
Zeigt alle verfügbaren Befehle an. |
soshelp <command> oder help <command> |
Zeigt den angegebenen Befehl an. |
syncblk |
Zeigt die Informationen zum SyncBlock-Container an. |
taskstate |
Zeigt einen Vorgangszustand in einem lesbaren Format an. |
threadpool |
Zeigt Informationen zum Threadpool der Runtime an. |
threadpoolqueue |
Zeigt Arbeitselemente für Threadpools in der Warteschlange an. |
threadstate |
Gibt die Bedeutung eines Threadszustands mit automatischer Strukturierung und Einrückung aus. |
threads <threadid> oder setthread <threadid> |
Legt die ID des aktuellen Threads für die SOS-Befehle fest oder zeigt diese an. |
timerinfo |
Zeigt Informationen zu ausgeführten Timern an. |
token2ee |
Zeigt die MethodTable-Struktur und die MethodDesc-Struktur für das angegebene Token und Modul an. |
traverseheap |
Schreibt Heapinformationen in einem vom CLR-Profiler lesbaren Format in eine Datei. |
verifyheap |
Überprüft den Garbage Collection-Heap auf Anzeichen einer Beschädigung. |
verifyobj |
Überprüft das Objekt, das als Argument für Anzeichen für Beschädigungen übergeben wird. |
Hinweis
Weitere Details finden Sie in SOS Debugging Extension für .NET.
dotnet-dump ps
Hiermit werden die dotnet-Prozesse aufgelistet, für die Speicherabbilder erfasst werden können.
Ab dotnet-dump-Version 6.0.320703 werden auch die Befehlszeilenargumente angezeigt, mit denen jeder Prozess gestartet wurde, sofern verfügbar.
Übersicht
dotnet-dump ps [-h|--help]
Beispiel
Angenommen, Sie starten eine zeitintensive App mit dem Befehl dotnet run --configuration Release. In einem anderen Fenster führen Sie den Befehl dotnet-dump ps aus. Die Ausgabe sieht wie folgt aus. Sofern vorhanden, werden die Befehlszeilenargumente ab dotnet-dump-Version 6.0.320703 angezeigt.
> dotnet-dump ps
21932 dotnet C:\Program Files\dotnet\dotnet.exe run --configuration Release
36656 dotnet C:\Program Files\dotnet\dotnet.exe
Verwenden von dotnet-dump
Der erste Schritt besteht im Sammeln eines Speicherabbilds. Dieser Schritt kann übersprungen werden, wenn bereits ein Kernspeicherabbild generiert wurde. Das Betriebssystem oder das integrierte Feature der .NET Core-Runtime dumpgenerierung können jeweils Kernabbilder erstellen.
$ dotnet-dump collect --process-id 1902
Writing minidump to file ./core_20190226_135837
Written 98983936 bytes (24166 pages) to core file
Complete
Analysieren Sie nun das Kernspeicherabbild mit dem Befehl analyze:
$ dotnet-dump analyze ./core_20190226_135850
Loading core dump: ./core_20190226_135850
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command.
Type 'quit' or 'exit' to exit the session.
>
Durch diese Aktion wird eine interaktive Sitzung aufgerufen, die Befehle wie die folgenden akzeptiert:
> clrstack
OS Thread Id: 0x573d (0)
Child SP IP Call Site
00007FFD28B42C58 00007fb22c1a8ed9 [HelperMethodFrame_PROTECTOBJ: 00007ffd28b42c58] System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo) [/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.Program.Foo4(System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.Program.Foo2(Int32, System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.Program.Foo1(Int32, System.String) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.Program.Main(System.String[]) [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]
00007FFD28B43210 00007fb22aa9cedf [GCFrame: 00007ffd28b43210]
00007FFD28B43610 00007fb22aa9cedf [GCFrame: 00007ffd28b43610]
So zeigen Sie einen Ausnahmefehler an, der Ihre App beendet hat
> pe -lines
Exception object: 00007fb18c038590
Exception type: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
InnerException: System.Exception, Use !PrintException 00007FB18C038368 to see more.
StackTrace (generated):
SP IP Function
00007FFD28B42DD0 0000000000000000 System.Private.CoreLib.dll!System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67 System.Private.CoreLib.dll!System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)+0xa7 [/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.dll!SymbolTestApp.Program.Foo4(System.String)+0x15d [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.dll!SymbolTestApp.Program.Foo2(Int32, System.String)+0x34 [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.dll!SymbolTestApp.Program.Foo1(Int32, System.String)+0x3a [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.dll!SymbolTestApp.Program.Main(System.String[])+0x6e [/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]
StackTraceString: <none>
HResult: 80131604
Analysieren von Speicherlecks und Zuordnungen
Speicherverluste treten auf, wenn Ihre App Verweise auf Objekte enthält, die nicht mehr benötigt werden, und verhindern, dass der Garbage Collector Arbeitsspeicher zurückgibt. Wird verwendet dotnet-dump , um Speicherlecks zu identifizieren, die größten Objekte zu finden und zu verstehen, wo Speicher verbraucht wird.
Eine vollständige exemplarische Vorgehensweise zum Debuggen eines Speicherverlusts finden Sie unter Debug eines Speicherverlusts in .NET.
Identifizieren der größten Objekte
Verwenden Sie den dumpheap Befehl mit der -stat Option, um eine Zusammenfassung der Objekte im Heap anzuzeigen, sortiert nach Gesamtgröße:
> dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007f6c1eeefba8 576 59904 System.Reflection.RuntimeMethodInfo
00007f6c1dc021c8 1749 95696 System.SByte[]
00000000008c9db0 3847 116080 Free
00007f6c1e784a18 175 128640 System.Char[]
00007f6c1dbf5510 217 133504 System.Object[]
00007f6c1dc014c0 467 416464 System.Byte[]
00007f6c21625038 6 4063376 testwebapi.Controllers.Customer[]
00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer
00007f6c1dc00f90 206770 19494060 System.String
Total 428516 objects
Diese Ausgabe zeigt Ihnen, welche Typen den meisten Arbeitsspeicher belegen. In diesem Beispiel System.String verbrauchen Objekte etwa 19 MB, und Customer Objekte verbrauchen etwa 4,8 MB.
Identifizieren von Objekten nach Namespace oder Assembly
Um zu ermitteln, welche Module oder Namespaces Arbeitsspeicher verbrauchen, verwenden Sie die -type Option mit einem teilweisen Typnamen, um Ergebnisse zu filtern:
> dumpheap -type MyCompany.Data -stat
Statistics:
MT Count TotalSize Class Name
00007f6c21625038 15000 3600000 MyCompany.Data.CustomerRecord
00007f6c21625040 8000 2560000 MyCompany.Data.OrderHistory
00007f6c21625048 2000 960000 MyCompany.Data.ProductCache
Total 25000 objects, 7120000 bytes
Mit diesem Ansatz können Sie ermitteln, welche Teile Ihrer Codebasis für den Arbeitsspeicherverbrauch verantwortlich sind.
Ermitteln der höchsten Anzahl von Instanziierungen
Um zu sehen, welche Typen die meisten Instanzen haben, unabhängig von der Gesamtgröße, sehen Sie sich die Spalte "Anzahl" in der dumpheap -stat Ausgabe an. Objekte mit hoher Instanzenanzahl können auf ineffiziente Probleme beim Erstellen oder Zwischenspeichern von Objekten hinweisen:
> dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007f6c1dc00f90 206770 19494060 System.String
00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer
00007f6c1dc021c8 1749 95696 System.SByte[]
Dieses Beispiel zeigt 206.770 String Instanzen und 200.000 Customer Instanzen.
Analysieren von Objektverweisen mit gcroot
Verwenden Sie gcroot nach dem Identifizieren großer oder zahlreicher Objekte herauszufinden, warum ein Objekt nicht garbage collection wird. Der gcroot Befehl zeigt die Referenzkette von GC-Wurzeln zu einem bestimmten Objekt an:
> dumpheap -mt 00007f6c20a67498
Address MT Size
00007f6ad09421f8 00007f6c20a67498 24
...
> gcroot 00007f6ad09421f8
Thread 3f68:
00007F6795BB58A0 00007F6C1D7D0745 testwebapi.Controllers.CustomerCache.GetAll()
rbx: (interior)
-> 00007F6BDFFFF038 System.Object[]
-> 00007F69D0033570 testwebapi.Controllers.Processor
-> 00007F69D0033588 testwebapi.Controllers.CustomerCache
-> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer]]
-> 00007F6C000148A0 testwebapi.Controllers.Customer[]
-> 00007F6AD0942258 testwebapi.Controllers.Customer
Found 1 root.
Diese Ausgabe zeigt, dass das Customer Objekt von einem CustomerCache Objekt gehalten wird, wodurch Sie die Quelle des Lecks in Ihrem Code identifizieren können.
Analysieren des Arbeitsspeichers nach Objektgröße
Verwenden Sie die -min Optionen -max , um Objekte nach Größe zu filtern:
> dumpheap -min 100000 -stat
Statistics:
MT Count TotalSize Class Name
00007f6c21625038 6 4063376 testwebapi.Controllers.Customer[]
00007f6c1dc014c0 12 416464 System.Byte[]
Total 18 objects
Mit diesem Befehl werden nur Objekte angezeigt, die größer als 100.000 Byte sind, sodass Sie sich auf die größten Speicherverbraucher konzentrieren können.
Deadlocks finden
Wird dotnet-dump verwendet, um Deadlock-Situationen zu diagnostizieren, in denen Threads blockiert werden, die auf Ressourcen warten. Eine vollständige exemplarische Vorgehensweise zum Debuggen von Deadlocks finden Sie unter Debug eines Deadlocks in .NET.
Alle Threads auflisten
Verwenden Sie den threads Befehl, um alle verwalteten Threads anzuzeigen:
> threads
*0 0x1DBFF (121855)
1 0x1DC01 (121857)
2 0x1DC02 (121858)
...
Untersuchen von Threadstapeln
Wird verwendet clrstack -all , um die Aufrufstapel aller Threads anzuzeigen:
> clrstack -all
Suchen Sie nach Mustern, in denen mehrere Threads für Monitor.Enter oder ähnliche Synchronisierungsgrundtypen blockiert werden.
Suchen von Sperrbesitzern
Verwenden Sie den syncblk Befehl, um zu sehen, welche Threads sperren und welche Threads warten:
> syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
43 00000246E51268B8 603 1 0000024B713F4E30 5634 28 00000249654b14c0 System.Object
44 00000246E5126908 3 1 0000024B713F47E0 51d4 29 00000249654b14d8 System.Object
In der Spalte "MonitorHeld " wird die Anzahl der Threads angezeigt, die auf die Sperre warten. In der Spalte "Owning Thread Info " wird angezeigt, welcher Thread die Sperre besitzt.
Erweiterte Speicheranalyseszenarien
Vergleichen mehrerer Dumps
Um das Speicherwachstum im Laufe der Zeit zu verstehen, sammeln Sie mehrere Abbilder, und vergleichen Sie sie:
- Erfassen eines Basisabbilds:
dotnet-dump collect -p <pid> -o baseline.dmp - Lassen Sie ihre App ausführen und mehr Arbeitsspeicher verbrauchen.
- Sammeln Sie ein zweites Dump:
dotnet-dump collect -p <pid> -o after.dmp - Analysieren Sie sowohl Dumps als auch vergleichen Sie die
dumpheap -statErgebnisse.
Suchen Sie nach Typen mit wesentlich mehr Instanzen oder größeren Gesamtgrößen im zweiten Dump.
Analysieren des Arbeitsspeichers für bestimmte Objekttypen
So sichern Sie alle Instanzen eines bestimmten Typs:
> dumpheap -type Customer
Address MT Size
00007f6ad09421f8 00007f6c20a67498 24
00007f6ad0942210 00007f6c20a67498 24
...
Verwenden Sie dann die Verwendung dumpobj , um einzelne Objekte zu untersuchen:
> dumpobj 00007f6ad09421f8
Name: testwebapi.Controllers.Customer
MethodTable: 00007f6c20a67498
EEClass: 00007f6c21625000
Size: 24(0x18) bytes
File: /app/testwebapi.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007f6c1dc00f90 4000001 8 System.String 0 instance 00007f6ad09421f0 Name
00007f6c1dbf4c18 4000002 10 System.Int32 1 instance 42 Id
Sammeln eines Dumps in einem Docker-Container
dotnet-dump erfordert ptrace Funktionen im Container. Eine häufige Möglichkeit, sie zu gewähren, besteht darin, den Container mit --cap-add=SYS_PTRACE. Je nach Umgebung müssen Sie möglicherweise auch das Seccomp-Profil des Containers anpassen. Informationen zur Diagnose von Sicherheitskonfigurationsproblemen in Containern finden Sie unter " Dumps: FAQ ".
Um dotnet-dump in einem Produktionsimage ohne das .NET SDK zu installieren, verwenden Sie die direct Downloadlinks aus dem Abschnitt "Installieren", oder verwenden Sie einen multi-stage Docker Build, um die Toolbinärdateien aus einem SDK-Image zu kopieren. Vollständige Anleitungen zur Containerdiagnose finden Sie unter Sammeln der Diagnose in Linux-Containern.
Problembehandlung bei der Sammlung von Speicherabbildern
Die Sammlung von Speicherabbildern erfordert, dass der Prozess ptrace aufgerufen werden kann. Wenn Probleme beim Sammeln von Speicherabbildern auftreten, ist die Ausführungsumgebung möglicherweise so konfiguriert, dass solche Aufrufe eingeschränkt werden. Unter Häufig gestellte Fragen zu Speicherabbildern finden Sie Tipps zur Problembehandlung und mögliche Lösungen für häufige Probleme.