Android
Last updated
Last updated
Below is a guide from the .NET Android Documentation:
Note that you can skip this step if the Android application is running on an Android emulator; it is only required for physical Android devices.
This will forward port 9000 on device to port 9001.
Alternatively:
This will allocate a random port on remote and forward it to port 9001 on the host. The forwarded port is printed by adb
dotnet-dsrouter
Generally, you can use a stable dotnet-dsrouter
from NuGet:
Or use a build from the nightly feed https://aka.ms/dotnet-tools/index.json
:
For profiling an Android application running on an Android emulator:
For profiling an Android application running on an Android device:
First, run dotnet-trace ps
to find a list of processes:
dotnet-trace
knows how to tell if a process ID is dotnet-dsrouter
and connect through it appropriately.
Using the process ID from the previous step, run dotnet-trace collect
:
NOTE: -f net8.0-android
is only needed for projects with multiple $(TargetFrameworks)
.
Once the application is installed and started, dotnet-trace
should show something similar to:
Once <Enter>
is pressed, you should see:
And the output files should be found in the current directory. You can use the -o
switch if you would prefer to output them to a specific directory.
If running on desktop, you can use the dotnet-gcdump
global tool. This can be installed via:
To use it, for example:
This will connect to a process and save a *.gcdump
file. You can open this file in Visual Studio on Windows, for example:
In .NET 8, we have a simplified method for collecing *.gcdump
files for Android applications. To get this data from an Android application, you need all the above setup for adb shell
, dsrouter
, etc. except you need to simply use dotnet-gcdump
instead of dotnet-trace
:
This will create a *.gcdump
file in the current directory.
In .NET 7, we have to use th older, more complicated method for collecting *.gcdump
files for Android applications. To get this data from an Android application, you need all the above setup for adb shell
, dsrouter
, etc.
0xC900001
, a bitmask, enables the following event types:
GCKeyword
GCHeapCollectKeyword
GCRootKeyword
This saves a .nettrace
file with GC events that are not available with the default provider.
To actually view this data, you'll have to use one of:
Using mono-gcdump
:
This saves a foo.gcdump
that you can open in Visual Studio.
dotnet trace
our build?Setting this up is easy, the main issue is there end up being potentially a lot of threads (30-40) depending on the build.
Before getting started, I would recommend doing these things to make the trace smaller and easier to understand:
Set $DOTNET_CLI_TELEMETRY_OPTOUT
to 1
, to avoid any dotnet CLI telemetry in the trace.
Profile a single .csproj
build, not a .sln
. This keeps the build in-process.
Always restore
in a separate step and use --no-restore
when you trace. This avoids NuGet logic in the trace.
Save a .binlog
, so you can review that the build actually did what you expected. dotnet trace
tends to hide all the console output.
So, for example, to profile a build:
This should result in .speedscope
and .nettrace
files in the current directory.
If you wanted to profile deploy & app launch, do a build first:
I found that "
is necessary when :
characters are present in the command. This appears to be some kind of argument parsing issue with dotnet trace
.
Eventually, we will be able to simply do dotnet-dsrouter android
when is resolved. adb reverse tcp:9000 tcp:9001
is also currently required as mentioned above.
The --format
argument is optional and it defaults to nettrace
. However, nettrace
files can be viewed only with Perfview on Windows, while the speedscope JSON files can be viewed "on" Unix by uploading them to
See the for further details about its usage.
See the for more info.
:4
enables "Informational" verbosity, where the different logging levels are described by .
See the for additional details.