To locate memory leaks in .NET 6.0 applications on Linux, you must use the dotnet-dump tool included with the SDK or installed via package managers like apt or yum. Unlike Windows which uses ProcDump, Linux relies on dotnet dump collect to generate minidumps, which are then analyzed using dotnet dump analyze with the SOS extension to inspect heap allocations and identify leaking objects.
Understanding the Linux Diagnostic Ecosystem
The primary confusion in cross-platform .NET diagnostics stems from naming conventions. On Windows, developers often rely on ProcDump to capture crash dumps because it is a lightweight, external utility. However, Microsoft designed the .NET Core runtime for Linux to be self-contained regarding diagnostic capabilities. The equivalent functionality is provided by thedotnet-dump tool, which interacts directly with the Common Language Runtime (CLR) and the operating system's debugging interfaces.
Attempting to install a "ProcDump" package on Ubuntu or RHEL will typically fail or result in a Windows-specific binary that cannot execute on Linux kernels. Therefore, the first step in resolving memory leak issues is ensuring you have the correct toolkit installed. This shift from external tools to integrated SDK utilities simplifies the workflow, as the same version of the runtime used to run your application can also diagnose it. For more context on managing .NET environments on Linux, you might find Issue with .NET HTTPS Development Certificate Not Trusted on Ubuntu 24.04 helpful, as certificate management often intersects with deployment troubleshooting.
Installing dotnet-dump
Before collecting any data, you need to ensure the diagnostic tools are available on your target machine. If you have the full .NET SDK installed,dotnet-dump is usually pre-installed. You can verify this by running:
dotnet dump --version
If the command is not found, you must install it explicitly. On Debian-based systems like Ubuntu, you can add the Microsoft package repository and install the tool:
sudo apt-get update
sudo apt-get install -y dotnet-sdk-6.0
# Or specifically the dump tool if separated in newer versions
sudo apt-get install -y dotnet-dump
On Red Hat Enterprise Linux (RHEL) or CentOS, use the yum or dnf package manager:
sudo yum install dotnet-sdk-6.0
sudo yum install dotnet-dump
Once installed, verify the installation again. This tool is capable of attaching to running processes, which is critical for production environments where restarting the application to catch a crash is not an option.
Collecting the Memory Dump
To diagnose a memory leak, you need a snapshot of the process's managed heap at a specific point in time. Identify the Process ID (PID) of your running .NET 6.0 application using standard Linux commands:ps aux | grep dotnet
Or use pgrep for a cleaner output:
pgrep -f myapp.dll
With the PID identified, collect the dump. The collect subcommand creates a minidump file. It is best practice to specify a name for the dump file to avoid overwriting previous captures during analysis:
dotnet dump collect -p <PID> -n myapp_leak.dmp
This command attaches to the running process, pauses it briefly to capture the state, and writes the dump to disk. The process resumes automatically after collection. Note that this operation requires read permissions to the target process, so you may need to run the command as the same user who owns the process, or use sudo if necessary. Be aware that attaching to a process can cause minor latency spikes, so perform this during low-traffic periods if possible. For broader system stability considerations, see Preserve Order of Closing Services While Shutting Down Linux, as improper shutdowns can sometimes mask or complicate diagnostic data.
Analyzing the Dump with SOS
The collected.dmp file is not human-readable. You must use the analyze subcommand along with the SOS (Son of Strike) debugger extension, which is the CLR equivalent of WinDbg extensions. Run the following command:
dotnet dump analyze myapp_leak.dmp
Once inside the SOS prompt (sos>), you can begin investigating. To see all objects on the managed heap, use:
dumpheap -stat
This lists types sorted by size, helping you identify which classes consume the most memory. Look for types with unexpectedly high instance counts or large total sizes. To drill down into a specific type, such as System.String or a custom class like UserContext, use:
dumpheap -type UserContext
To understand why these objects are being retained, you need to find their roots. Use the gcroot command on a specific object address obtained from dumpheap:
gcroot <object_address>
This reveals the chain of references keeping the object alive. A common pattern in memory leaks is static collections or event handlers that are never unsubscribed. By tracing the root, you can pinpoint the code location responsible for holding the reference.
Common Leak Patterns in .NET 6
When analyzing dumps, look for three common culprits. First, event subscriptions without unsubscription. If you subscribe to an event in a short-lived service but the publisher lives longer, the subscriber remains in memory. Second, static caches that grow indefinitely. Ensure you implement eviction policies or useIMemoryCache with expiration settings. Third, unmanaged resources not disposed properly. While garbage collection handles managed memory, native handles (like file streams or database connections) require explicit disposal via IDisposable. Using dumpheap -stat helps distinguish between managed heap pressure and potential unmanaged resource leaks by correlating with native memory usage metrics from top or htop.
Frequently Asked Questions
Can I use ProcDump on Linux?
No, ProcDump is a Windows-only utility maintained by Microsoft for capturing Windows crash dumps. It does not function on Linux kernels. You must usedotnet-dump instead, which provides equivalent functionality for .NET applications on Linux.
What if dotnet-dump fails to attach to the process?
This usually happens due to permission issues or security restrictions. Ensure you are running the command as the same user who owns the process. Additionally, check if/proc/sys/kernel/yama/ptrace_scope is set to restrict parent-child debugging relationships; setting it to 0 allows broader attachment capabilities.
How do I reduce the size of the dump file?
By default,dotnet dump collect creates a minidump, which includes only the managed heap and thread states. This is sufficient for most memory leak analysis and keeps file sizes manageable. Avoid using full memory dumps unless directed by support, as they contain the entire physical memory space and can be gigabytes in size.
Can I analyze the dump on a different machine?
Yes, you can copy the.dmp file to another machine running the same .NET 6.0 version and analyze it there. However, you must have the exact same assembly versions (DLLs) available on the analysis machine for SOS to resolve symbols correctly. Mismatched versions can lead to inaccurate type information.
Is there a way to automate dump collection?
You can write a script that monitors memory usage thresholds and triggersdotnet dump collect when limits are exceeded. Alternatively, configure your application to generate dumps on unhandled exceptions using environment variables like COMPlus_DbgEnableMiniDump=1, which instructs the CLR to create a dump automatically upon crash.