Spåra .NET-program med PerfCollect
Den här artikeln gäller för: ✔️ .NET Core 2.1 SDK och senare versioner
När prestandaproblem uppstår i Linux kan insamling av en spårning med perfcollect
användas för att samla in detaljerad information om vad som hände på datorn vid tidpunkten för prestandaproblemet.
perfcollect
är ett bash-skript som använder Linux Trace Toolkit: nästa generation (LTTng) för att samla in händelser som skrivits från körningen eller någon EventSource, samt perf för att samla in CPU-exempel på målprocessen.
Förbereda datorn
Följ de här stegen för att förbereda datorn för att samla in en prestandaspårning med perfcollect
.
Kommentar
Om du samlar in inifrån en container måste containern ha rätt funktioner. De minsta nödvändiga funktionerna är PERFMON
och SYS_PTRACE
. Om avbildningen misslyckas med den minimala uppsättningen lägger du till SYS_ADMIN
funktionen i containern. Mer information om hur du spårar program i containrar med PerfCollect finns i Samla in diagnostik i containrar.
Ladda ned
perfcollect
.curl -OL https://aka.ms/perfcollect
Gör skriptet körbart.
chmod +x perfcollect
Installera krav för spårning – det här är de faktiska spårningsbiblioteken.
sudo ./perfcollect install
Detta installerar följande krav på datorn:
perf
: Undersystemet För Linux-prestandahändelser och tillhörande samling/visningsprogram för användarläge.perf
är en del av Linux-kernelkällan, men installeras vanligtvis inte som standard.LTTng
: Används för att samla in händelsedata som genereras vid körning av CoreCLR. Dessa data används sedan för att analysera beteendet för olika körningskomponenter, till exempel GC, JIT och trådpoolen.
De senaste versionerna av .NET Core och Linux-verktyget har stöd för automatisk lösning av metodnamn för ramverkskod.
För att matcha metodnamn för interna körnings-DLL:er (till exempel libcoreclr.so) perfcollect
löser du symboler för dem när de konverterar data, men bara om symbolerna för dessa binärfiler finns. Mer information finns i Hämta symboler för den interna körningen .
Samla in en spårning
Ha två tillgängliga gränssnitt – ett för att kontrollera spårning, som kallas [Trace] och ett för att köra programmet, som kallas [App].
[Spårning] Starta samlingen.
sudo ./perfcollect collect sampleTrace
Förväntad utdata:
Collection started. Press CTRL+C to stop.
[App] Konfigurera programgränssnittet med följande miljövariabler – detta möjliggör spårningskonfiguration av CoreCLR.
export DOTNET_PerfMapEnabled=1 export DOTNET_EnableEventLog=1
Kommentar
När du kör appen med .NET 7 måste du också ange
DOTNET_EnableWriteXorExecute=0
utöver föregående miljövariabler. Till exempel:export DOTNET_EnableWriteXorExecute=0
Kommentar
.NET 6 standardiserar på prefixet
DOTNET_
i ställetCOMPlus_
för för miljövariabler som konfigurerar .NET-körningsbeteende. PrefixetCOMPlus_
fortsätter dock att fungera. Om du använder en tidigare version av .NET-körningen bör du fortfarande använda prefixetCOMPlus_
för miljövariabler.[App] Kör appen – låt den köras så länge du behöver för att samla in prestandaproblemet. Den exakta längden kan vara så kort som du behöver så länge den tillräckligt fångar upp tidsperioden där det prestandaproblem som du vill undersöka inträffar.
dotnet run
[Spårning] Stoppa samling – tryck på CTRL+C.
^C ...STOPPED. Starting post-processing. This may take some time. Generating native image symbol files ...SKIPPED Saving native symbols ...FINISHED Exporting perf.data file ...FINISHED Compressing trace files ...FINISHED Cleaning up artifacts ...FINISHED Trace saved to sampleTrace.trace.zip
Den komprimerade spårningsfilen lagras nu i den aktuella arbetskatalogen.
Visa en spårning
Det finns ett antal alternativ för att visa spårningen som har samlats in. Spårningar visas bäst med PerfView i Windows, men de kan visas direkt i Linux med hjälp av PerfCollect
sig själv eller TraceCompass
.
Använd PerfCollect för att visa spårningsfilen
Du kan använda själva perfcollect för att visa spårningen som du har samlat in. Använd följande kommando för att göra detta:
./perfcollect view sampleTrace.trace.zip
Som standard visar detta cpu-spårningen av programmet med hjälp av perf
.
Om du vill titta på de händelser som har samlats in via LTTng
kan du skicka in flaggan -viewer lttng
för att se de enskilda händelserna:
./perfcollect view sampleTrace.trace.zip -viewer lttng
Då används babeltrace
visningsprogrammet för att skriva ut nyttolasten för händelser:
# [01:02:18.189217659] (+0.020132603) ubuntu-xenial DotNETRuntime:ExceptionThrown_V1: { cpu_id = 0 }, { ExceptionType = "System.Exception", ExceptionMessage = "An exception happened", ExceptionEIP = 139875671834775, ExceptionHRESULT = 2148734208, ExceptionFlags = 16, ClrInstanceID = 0 }
# [01:02:18.189250227] (+0.020165171) ubuntu-xenial DotNETRuntime:ExceptionCatchStart: { cpu_id = 0 }, { EntryEIP = 139873639728404, MethodID = 139873626968120, MethodName = "void [helloworld] helloworld.Program::Main(string[])", ClrInstanceID = 0 }
Använd PerfView för att öppna spårningsfilen
Om du vill se en samlingsvy över både CPU-exemplet och händelserna kan du använda PerfView
på en Windows-dator.
Kopiera trace.zip-filen från Linux till en Windows-dator.
Ladda ned PerfView från https://aka.ms/perfview.
Kör PerfView.exe
PerfView.exe <path to trace.zip file>
PerfView visar listan över vyer som stöds baserat på data i spårningsfilen.
För CPU-undersökningar väljer du CPU-stackar.
För detaljerad GC-information väljer du GCStats.
För JIT-information per process/modul/metod väljer du JITStats.
Om det inte finns någon vy för den information du behöver kan du försöka leta efter händelserna i vyn råhändelser. Välj Händelser.
Mer information om hur du tolkar vyer i PerfView finns i hjälplänkar i själva vyn, eller från huvudfönstret i PerfView väljer du Hjälp-användarhandbok>.
Kommentar
Händelser som skrivs via System.Diagnostics.Tracing.EventSource API (inklusive händelser från Framework) visas inte under leverantörens namn. I stället skrivs de som EventSourceEvent
händelser under Microsoft-Windows-DotNETRuntime
providern och deras nyttolaster är JSON-serialiserade.
Kommentar
Om du ser [unknown] /memfd:doublemapper
bildrutor i metodnamn och anropstackar anger DOTNET_EnableWriteXorExecute=0
du innan du kör appen som du spårar med perfcollect.
Använd TraceCompass för att öppna spårningsfilen
Eclipse TraceCompass är ett annat alternativ som du kan använda för att visa spårningarna. TraceCompass
fungerar även på Linux-datorer, så du behöver inte flytta spårningen över till en Windows-dator. Om du vill öppna TraceCompass
spårningsfilen måste du packa upp filen.
unzip myTrace.trace.zip
perfcollect
sparar LTTng-spårningen som samlas in i ett CTF-filformat i en underkatalog i lttngTrace
. Mer specifikt finns CTF-filen i en katalog som ser ut som lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\
.
Du kan öppna CTF-spårningsfilen genom TraceCompass
att File -> Open Trace
välja och välja metadata
filen.
Mer information finns i TraceCompass
dokumentationen.
Hämta symboler för den interna körningen
För det mesta är du intresserad av din egen kod, som perfcollect
matchar som standard. Ibland är det bra att se vad som händer i .NET-DLL:er (vilket är vad det sista avsnittet handlade om), men ibland är det som händer i de interna runtime-dll:erna (vanligtvis libcoreclr.so) intressant. perfcollect
kommer att matcha symbolerna för dessa när de konverterar sina data, men bara om symbolerna för dessa interna DLL:er finns (och finns bredvid det bibliotek de är för).
Det finns ett globalt kommando med namnet dotnet-symbol som gör detta. Så här använder du dotnet-symbol för att hämta inbyggda körningssymboler:
Installera
dotnet-symbol
:dotnet tool install -g dotnet-symbol
Ladda ned symbolerna. Om den installerade versionen av .NET Core-körningen är 2.1.0 är kommandot för att göra detta:
mkdir mySymbols dotnet symbol --symbols --output mySymbols /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
Kopiera symbolerna till rätt plats.
sudo cp mySymbols/* /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0
Om detta inte kan göras eftersom du inte har skrivåtkomst till rätt katalog kan du använda
perf buildid-cache
för att lägga till symbolerna.
Efter detta bör du få symboliska namn för de inbyggda dll:erna när du kör perfcollect
.
Samla in i en Docker-container
Mer information om hur du använder perfcollect
i containermiljöer finns i Samla in diagnostik i containrar.
Läs mer om samlingsalternativ
Du kan ange följande valfria flaggor med perfcollect
för att bättre passa dina diagnostikbehov.
Samla in under en viss tidsperiod
När du vill samla in en spårning under en viss tidsperiod kan du använda -collectsec
alternativet följt av ett tal som anger det totala antalet sekunder som en spårning ska samlas in för.
Samla in threadtime-spårningar
Om du anger -threadtime
med perfcollect
kan du samla in cpu-användningsdata per tråd. På så sätt kan du analysera var varje tråd spenderade sin CPU-tid.
Samla in spårningar för hanterat minne och skräpinsamlingsprestanda
Med följande alternativ kan du specifikt samla in GC-händelserna från körningen.
perfcollect collect -gccollectonly
Samla endast in en minimal uppsättning GC-samlingshändelser. Det här är den minst utförliga GC-händelseinsamlingsprofilen med den lägsta effekten på målappens prestanda. Det här kommandot motsvarar PerfView.exe /GCCollectOnly collect
kommandot i PerfView.
perfcollect collect -gconly
Samla in mer utförliga GC-samlingshändelser med JIT-, Loader- och Exception-händelser. Detta begär mer utförliga händelser (till exempel allokeringsinformation och GC-kopplingsinformation) och har större inverkan på målappens prestanda än -gccollectonly
alternativet. Det här kommandot motsvarar PerfView.exe /GCOnly collect
kommandot i PerfView.
perfcollect collect -gcwithheap
Samla in de mest utförliga GC-samlingshändelserna, som också spårar heapens överlevnad och rörelser. Detta ger djupgående analys av GC-beteendet men medför höga prestandakostnader eftersom varje GC kan ta mer än två gånger längre tid. Vi rekommenderar att du förstår prestandakonsekvenserna av att använda det här spårningsalternativet när du spårar i produktionsmiljöer.