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 bezieht sich auf: ✔️ .NET Core 3.1 SDK und höhere Versionen
In diesem Lernprogramm erfahren Sie, wie Sie ein übermäßiges CPU-Auslastungsszenario debuggen. Mithilfe des bereitgestellten Beispiels ASP.NET Core Web App Quellcode-Repository können Sie absichtlich zu einem Deadlock führen. Der Endpunkt reagiert nicht mehr und erlebt die Threadakkumulation. Sie erfahren, wie Sie verschiedene Tools verwenden können, um dieses Szenario mit mehreren wichtigen Diagnosedaten zu diagnostizieren.
In diesem Lernprogramm wird Folgendes vermittelt:
- Untersuchen der hohen CPU-Auslastung
- Ermitteln der CPU-Auslastung mit Dotnet-Leistungsindikatoren
- Verwenden von dotnet-trace für die Ablaufverfolgungsgenerierung
- Profilleistung in PerfView
- Diagnostizieren und Lösen einer übermäßigen CPU-Auslastung
Voraussetzungen
Das Lernprogramm verwendet:
- .NET Core 3.1 SDK oder eine höhere Version.
- Beispieldebugziel zum Auslösen des Szenarios.
- dotnet-trace to list processes and generate a profile.
- dotnet-counters to monitor cpu usage.
CPU-Leistungsindikatoren
Bevor Sie dieses Lernprogramm versuchen, installieren Sie bitte die neueste Version von dotnet-counters:
dotnet tool install --global dotnet-counters
Wenn Ihre App eine version von .NET ausführt, die älter als .NET 9 ist, sieht die Ausgabebenutzeroberfläche von dotnet-counters etwas anders aus. Weitere Informationen finden Sie unter dotnet-counters .
Bevor Sie versuchen, Diagnosedaten zu sammeln, müssen Sie eine hohe CPU-Bedingung beobachten. Führen Sie die Beispielanwendung mit dem folgenden Befehl aus dem Projektstammverzeichnis aus.
dotnet run
Verwenden Sie den Befehl "dotnet-counters ", um die aktuelle CPU-Auslastung zu überprüfen:
dotnet-counters monitor -n DiagnosticScenarios --showDeltas
Die Ausgabe sollte etwa wie folgt aussehen:
Press p to pause, r to resume, q to quit.
Status: Running
Name Current Value Last Delta
[System.Runtime]
dotnet.assembly.count ({assembly}) 111 0
dotnet.gc.collections ({collection})
gc.heap.generation
------------------
gen0 8 0
gen1 1 0
gen2 0 0
dotnet.gc.heap.total_allocated (By) 4,042,656 24,512
dotnet.gc.last_collection.heap.fragmentation.size (By)
gc.heap.generation
------------------
gen0 801,728 0
gen1 6,048 0
gen2 0 0
loh 0 0
poh 0 0
dotnet.gc.last_collection.heap.size (By)
gc.heap.generation
------------------
gen0 811,512 0
gen1 562,024 0
gen2 1,095,056 0
loh 98,384 0
poh 24,528 0
dotnet.gc.last_collection.memory.committed_size (By) 5,623,808 0
dotnet.gc.pause.time (s) 0.019 0
dotnet.jit.compilation.time (s) 0.582 0
dotnet.jit.compiled_il.size (By) 138,895 0
dotnet.jit.compiled_methods ({method}) 1,470 0
dotnet.monitor.lock_contentions ({contention}) 4 0
dotnet.process.cpu.count ({cpu}) 22 0
dotnet.process.cpu.time (s)
cpu.mode
--------
system 0.109 0
user 0.453 0
dotnet.process.memory.working_set (By) 65,515,520 0
dotnet.thread_pool.queue.length ({work_item}) 0 0
dotnet.thread_pool.thread.count ({thread}) 0 0
dotnet.thread_pool.work_item.count ({work_item}) 6 0
dotnet.timer.count ({timer}) 0 0
Wenn Sie sich auf die Last Delta
Werte dotnet.process.cpu.time
konzentrieren, teilen sie uns mit, wie viele Sekunden innerhalb des Aktualisierungszeitraums (derzeit auf den Standardwert von 1 s festgelegt) die CPU aktiv war. Wenn die Web-App unmittelbar nach dem Start ausgeführt wird, wird die CPU überhaupt nicht verbraucht, und diese Deltas sind beide 0
. Navigieren Sie zur api/diagscenario/highcpu
Route mit 60000
dem Parameter "Route":
https://localhost:5001/api/diagscenario/highcpu/60000
Führen Sie nun den Befehl "dotnet-counters" erneut aus.
dotnet-counters monitor -n DiagnosticScenarios --showDeltas
Wie unten dargestellt, sollte eine Zunahme der CPU-Auslastung angezeigt werden (je nach Hostcomputer erwarten Sie unterschiedliche CPU-Auslastung):
Press p to pause, r to resume, q to quit.
Status: Running
Name Current Value Last Delta
[System.Runtime]
dotnet.assembly.count ({assembly}) 111 0
dotnet.gc.collections ({collection})
gc.heap.generation
------------------
gen0 8 0
gen1 1 0
gen2 0 0
dotnet.gc.heap.total_allocated (By) 4,042,656 24,512
dotnet.gc.last_collection.heap.fragmentation.size (By)
gc.heap.generation
------------------
gen0 801,728 0
gen1 6,048 0
gen2 0 0
loh 0 0
poh 0 0
dotnet.gc.last_collection.heap.size (By)
gc.heap.generation
------------------
gen0 811,512 0
gen1 562,024 0
gen2 1,095,056 0
loh 98,384 0
poh 24,528 0
dotnet.gc.last_collection.memory.committed_size (By) 5,623,808 0
dotnet.gc.pause.time (s) 0.019 0
dotnet.jit.compilation.time (s) 0.582 0
dotnet.jit.compiled_il.size (By) 138,895 0
dotnet.jit.compiled_methods ({method}) 1,470 0
dotnet.monitor.lock_contentions ({contention}) 4 0
dotnet.process.cpu.count ({cpu}) 22 0
dotnet.process.cpu.time (s)
cpu.mode
--------
system 0.344 0.013
user 14.203 0.963
dotnet.process.memory.working_set (By) 65,515,520 0
dotnet.thread_pool.queue.length ({work_item}) 0 0
dotnet.thread_pool.thread.count ({thread}) 0 0
dotnet.thread_pool.work_item.count ({work_item}) 6 0
dotnet.timer.count ({timer}) 0 0
Während der gesamten Dauer der Anforderung wird die CPU-Auslastung auf den erhöhten Wert zeigen.
Tipp
Um eine noch höhere CPU-Auslastung zu visualisieren, können Sie diesen Endpunkt gleichzeitig auf mehreren Browserregisterkarten ausführen.
An diesem Punkt können Sie sicher sagen, dass die CPU höher ist als erwartet. Die Identifizierung der Auswirkungen eines Problems ist entscheidend, um die Ursache zu finden. Wir verwenden zusätzlich zu Diagnosetools die Auswirkungen des hohen CPU-Verbrauchs, um die Ursache des Problems zu finden.
Analysieren hoher CPU mit Profiler
Bei der Analyse einer App mit hoher CPU-Auslastung benötigen Sie ein Diagnosetool, das Einblicke in die Funktionsweise des Codes liefern kann. Die übliche Wahl ist ein Profiler, und es gibt verschiedene Profileroptionen, aus denen Sie wählen können.
dotnet-trace
kann jedoch auf allen Betriebssystemen verwendet werden, die Einschränkungen von Safe-Point Bias und managed-only Callstacks führen zu allgemeineren Informationen im Vergleich zu einem kernelfähigen Profiler wie "perf" für Linux oder ETW für Windows. Wenn Ihre Leistungsuntersuchung nur verwalteten Code umfasst, reicht dies im Allgemeinen dotnet-trace
aus.
Das perf
Tool kann zum Generieren von .NET Core-App-Profilen verwendet werden. Wir zeigen dieses Tool, obwohl auch dotnet-trace verwendet werden könnte. Beenden Sie die vorherige Instanz des Beispieldebugziels.
Legen Sie die DOTNET_PerfMapEnabled
Umgebungsvariable fest, damit die .NET-App eine map
Datei im /tmp
Verzeichnis erstellt. Diese map
Datei wird verwendet perf
, um CPU-Adressen jiT-generierten Funktionen nach Namen zuzuordnen. Weitere Informationen finden Sie unter Exportieren von perf-Karten und Jit-Dumps.
Hinweis
.NET 6 standardisiert das Präfix DOTNET_
anstelle von COMPlus_
für Umgebungsvariablen, die das .NET-Laufzeitverhalten konfigurieren. Das Präfix COMPlus_
funktioniert jedoch weiterhin. Wenn Sie eine frühere Version der .NET-Laufzeit verwenden, sollten Sie weiterhin das präfix COMPlus_
für Umgebungsvariablen verwenden.
Führen Sie das Beispieldebugziel in derselben Terminalsitzung aus.
export DOTNET_PerfMapEnabled=1
dotnet run
Üben Sie den endpunkt der hohen CPU-API (https://localhost:5001/api/diagscenario/highcpu/60000
) erneut aus. Während sie innerhalb der 1-minütigen Anforderung ausgeführt wird, führen Sie den perf
Befehl mit Ihrer Prozess-ID aus:
sudo perf record -p 2266 -g
Der perf
Befehl startet den Prozess der Leistungsauflistung. Lassen Sie die Ausführung etwa 20 bis 30 Sekunden dauern, und drücken Sie dann STRG+C , um den Sammlungsprozess zu beenden. Sie können denselben perf
Befehl verwenden, um die Ausgabe der Ablaufverfolgung anzuzeigen.
sudo perf report -f
Sie können auch ein Flammendiagramm mithilfe der folgenden Befehle generieren:
git clone --depth=1 https://github.com/BrendanGregg/FlameGraph
sudo perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > flamegraph.svg
Dieser Befehl generiert einen flamegraph.svg
, den Sie im Browser anzeigen können, um das Leistungsproblem zu untersuchen:
Analysieren hoher CPU-Daten mit Visual Studio
Alle *.nettrace-Dateien können in Visual Studio analysiert werden. Um eine Linux *.nettrace-Datei in Visual Studio zu analysieren, übertragen Sie die Datei *.nettrace zusätzlich zu den anderen erforderlichen Dokumenten auf einen Windows-Computer, und öffnen Sie dann die Datei *.nettrace in Visual Studio. Weitere Informationen finden Sie unter "Analysieren von CPU-Auslastungsdaten".
Siehe auch
- dotnet-trace to list processes
- dotnet-counters to check managed memory usage
- dotnet-dump zum Sammeln und Analysieren einer Dumpdatei
- dotnet/diagnostics