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:4option, and usemono-gcdump convertto 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 --interactivelike 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-dsroutertool usingdotnet tool install --global dotnet-dsrouter. - Connect to your Android device using
adband runadb shell setprop debug.mono.profile '127.0.0.1:9000,suspend'. - Run your application on the device.
- Make sure the
ANDROID_SDK_ROOTenvironment 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 usemylocalportinstead of~/mylocalport) - Run
mono-gcdump collect --interactive --diagnostic-port ~/mylocalport,connect -o memory.gcdump. - Press
dkey to collect a dump. - Open the generated
memory_1.gcdumpfile 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=1environment variable. - Run
mono-gcdump collect --interactive -p <process id> -o memory.gcdump. - Press
dkey to collect a dump. - Open the generated
memory_1.gcdumpfile 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.
