The mono-gcdump tool is a close cousin to the dotnet-gcdump tool. It produces .gcdump files from MonoVM processes that capture the managed heap state for analysis. The gcdump files can be viewed in Visual Studio, PerfView, or dotnet-heapview.
NOTE: If you are using .NET 8 or newer, use the official dotnet-gcdump tool instead of mono-gcdump. The runtime was updated to support the same tooling available on other platforms.
There are three ways to use the tool:
- Capture a .nettrace file using the dotnet-trace tool with the
collect --providers Microsoft-DotNETRuntimeMonoProfiler:0xC900003:4
option, and usemono-gcdump convert
to turn the .nettrace file into .gcdump file. - Use
mono-gcdump collect -p <process id>
on a running process, ormono-gcdump collect --diagnostic-port <diagnostic port>
if using dotnet-dsrouter with a mobile application. This produces the .gcdump file directly. - Use
mono-gcdump collect --interactive
like the option above to collect more GC dumps of the same process. This is particularly useful with the option to diff multiple .gcdump files in Visual Studio.
- Install the
dotnet-dsrouter
tool usingdotnet tool install --global dotnet-dsrouter
. - Connect to your Android device using
adb
and runadb shell setprop debug.mono.profile '127.0.0.1:9000,suspend'
. - Run your application on the device.
- Make sure the
ANDROID_SDK_ROOT
environment variable points to the Android SDK location. - Run
dotnet-dsrouter server-server -ipcs ~/mylocalport -tcps 127.0.0.1:9000 --forward-port Android
(on Windows usemylocalport
instead of~/mylocalport
) - Run
mono-gcdump collect --interactive --diagnostic-port ~/mylocalport,connect -o memory.gcdump
. - Press
d
key to collect a dump. - Open the generated
memory_1.gcdump
file in your tool of choice.
Follow the dotnet-dsrouter documentation for more details on how to setup the diagnostic ports, and for troubleshooting common issues.
- Publish your application with the Mono Runtime (
-p:UseMonoRuntime=true -r <runtime identifier>
) and run the published executable withDOTNET_DefaultDiagnosticPortSuspend=1
environment variable. - Run
mono-gcdump collect --interactive -p <process id> -o memory.gcdump
. - Press
d
key to collect a dump. - Open the generated
memory_1.gcdump
file in your tool of choice.
Normally the tool tries to attribute the GC roots into different sections, such as "Thread stack", "Finalizer", "Static variables", etc.
Unfortunately due to the limitations of the Mono Log Profiler API this only works in the collect --interactive
mode if the collection is started right from the process start. This enables capturing the "GC root register" and "GC root unregister" events that enable proper attribution of the GC root addresses.
Furthermore, the "GC roots" event incorrectly reports the addresses, so a runtime with this fix is necessary.
The Mono Log Profiler API currently doesn't offer a trivial way to map addresses to static variable names.
The tool is licensed under the MIT license. It uses portions of the tools and libraries from dotnet/diagnostics and PerfView.