Memory problems in production are difficult to investigate because the application may continue running while memory usage keeps increasing.
A common reaction is to restart the application. Restarting can recover memory temporarily, but it also removes valuable diagnostic information. Objects that were consuming memory, blocked threads, large allocations, and the managed heap state can disappear as soon as the process stops.
A memory dump gives developers a snapshot of the running process that can be analyzed later.
In .NET applications, you can create a memory dump from a running process without restarting the application. This is especially useful when investigating memory leaks, excessive memory usage, unexpected garbage collection behavior, or high process memory.
This article explains how to collect a memory dump from a running C# application, what information the dump contains, how to collect it safely in production, and how to analyze it afterward.
What Is a Memory Dump?
A memory dump is a snapshot of a process at a particular point in time.
For a .NET application, the dump can contain information about:
Managed objects
Managed heap state
Threads
Stack information
Loaded assemblies
Native memory
Runtime information
Exception state
Application state
The exact information available depends on the dump type and platform.
Conceptually, the process looks like this:
Running .NET Application
|
v
Process Memory
|
v
Memory Dump
|
v
Analyze LaterThe important part is that creating the dump does not require stopping and restarting the application.
Why Create a Dump Without Restarting?
Restarting an application can hide the original problem.
Consider an application whose memory usage looks like this:
08:00 - 2 GB
09:00 - 3 GB
10:00 - 5 GB
11:00 - 8 GBAt 11:00, the application may be approaching its memory limit.
If you restart it:
8 GB
|
v
Restart
|
v
2 GBThe immediate memory problem appears to disappear.
But the objects that caused the memory growth are no longer available for investigation.
A dump collected before the restart can preserve useful diagnostic information.
When Should You Collect a Memory Dump?
A memory dump can be useful when you see symptoms such as:
Increasing process memory
Frequent garbage collections
Out-of-memory exceptions
Unexpected application slowdown
Large managed heap
Threading problems
Suspected memory leaks
Increasing container memory usage
Memory usage that does not fall after garbage collection
Do not automatically create a dump every time memory increases.
First confirm that the process is experiencing a meaningful problem.
What You Need Before Collecting a Dump
Before collecting a production dump, identify:
The process ID.
The operating system.
The .NET runtime version.
Available disk space.
The location where the dump will be stored.
Whether your production policy permits process dumps.
Whether the dump could contain sensitive information.
A dump can contain application data that was present in memory.
For example:
Passwords
Tokens
Connection information
Customer data
Request data
Personal informationDo not treat a production memory dump like an ordinary log file.
Using dotnet-dump
The .NET diagnostics tools include dotnet-dump, which can be used to collect and analyze dumps from .NET processes.
A typical workflow is:
Find process
|
v
Collect dump
|
v
Copy dump if required
|
v
Analyze dump
|
v
Identify memory problemThe tool can collect a dump from a running .NET process.
Step 1 - Find the Running Process
Start by listing the running .NET processes.
dotnet-dump psThe output can identify processes such as:
12345 MyApplication
15678 WorkerService
17321 ApiServiceThe number is the process ID.
For example:
PID = 12345You can also identify the process through the operating system's normal process-management tools.
The important point is to make sure you select the correct application before collecting a dump.
Step 2 - Check Available Disk Space
A dump file can be large.
Before collecting it, check the available disk space:
df -hon Linux systems.
On Windows, check the available space on the drive where the dump will be written.
Do not assume that a dump will always be small.
The required storage depends on the process and the type of dump being collected.
Step 3 - Collect the Dump
A basic dotnet-dump command looks like this:
dotnet-dump collect --process-id 12345 --output /tmp/myapp.dmpThe important parameters are:
--process-idThis identifies the running process.
--outputThis specifies where the dump should be written.
For example:
dotnet-dump collect \
--process-id 12345 \
--output /tmp/myapp-memory.dmpThe application continues running while the dump is collected.
The exact collection behavior and available dump options can depend on the operating system and runtime.
What Happens During Collection?
At a high level:
.NET Process
|
| 1. Diagnostic request
v
Dump collection
|
| 2. Capture process state
v
.dmp file
|
| 3. Application continues
v
Running applicationThe application is not intentionally restarted as part of the dump collection process.
However, collecting a dump is not free.
The process can experience additional CPU, memory, and I/O activity while the snapshot is being created.
For this reason, dump collection should still be treated as a production diagnostic operation.
Full Dump vs Smaller Diagnostic Data
A full process dump can contain a large amount of memory.
That can be useful when investigating:
Object retention
Managed heap problems
Native memory
Memory corruption
Complex runtime issues
But a larger dump also means:
More disk usage
Longer collection time
More data to transfer
Greater security exposure
More storage requirements
Choose the collection approach based on the problem you are investigating.
Do not collect the largest possible dump simply because it contains more information.
Example Production Workflow
Suppose an ASP.NET Core API is running on Linux.
The application has:
PID: 12345
Memory: 7.8 GBThe normal memory usage is approximately:
2 - 3 GBThe first step is to confirm the process:
dotnet-dump psThen collect the dump:
dotnet-dump collect \
--process-id 12345 \
--output /var/tmp/api-memory.dmpAfter collection, verify the file:
ls -lh /var/tmp/api-memory.dmpThe application can continue serving requests while the dump is moved for analysis.
Moving a Production Dump
A production dump should be handled carefully.
A typical workflow is:
Production Server
|
v
Collect dump
|
v
Secure storage
|
v
Diagnostic environment
|
v
AnalysisAvoid leaving diagnostic dumps on production servers indefinitely.
Once the investigation is complete, follow your organization's retention and deletion requirements.
Analyzing the Dump
After collecting the dump, open it using dotnet-dump.
For example:
dotnet-dump analyze /tmp/myapp-memory.dmpYou can then use diagnostic commands from the interactive session.
A useful first command is:
dumpheap -statThis can provide information about managed objects and their memory usage.
A simplified result might look like:
Count Total Size Type
------------------------------------------------
125000 48 MB System.String
85000 35 MB MyApp.Customer
42000 28 MB MyApp.Order
12000 22 MB System.Byte[]This kind of information can help identify object types that are consuming significant amounts of managed memory.
Finding Large Objects
Large objects can contribute significantly to memory pressure.
For example, a service that repeatedly creates large byte arrays may produce:
public byte[] CreateBuffer()
{
return new byte[10_000_000];
}If references to those arrays remain alive longer than expected, memory usage can increase.
A heap analysis can help determine whether large object types are accumulating.
The important question is not simply:
Which object is large?It is:
Why is this object still reachable?Finding Object Retention
Suppose the dump shows many instances of:
MyApp.SessionThe next question is why those objects have not been collected.
Possible causes include:
Static collection
|
v
Session objectsor:
Long-lived service
|
v
Cache
|
v
Session objectsThe dump can help developers follow object references and determine why memory remains reachable.
This is often more useful than simply looking at total process memory.
Memory Usage Does Not Always Mean a Memory Leak
High memory usage does not automatically mean that the application has a memory leak.
The application may legitimately allocate memory for:
Caching
Large requests
Serialization
Background processing
Temporary buffers
Database operations
For example:
var results = await repository.GetLargeResultSetAsync();
var response = JsonSerializer.Serialize(results);This can create several in-memory representations of the same logical data.
A better investigation should therefore look at memory behavior over time rather than assuming that high memory equals a leak.
Compare Multiple Dumps
One dump provides a snapshot.
Two or more dumps can provide a trend.
For example:
Dump 1
2.5 GB
|
| 30 minutes
v
Dump 2
4.0 GB
|
| 30 minutes
v
Dump 3
6.5 GBIf the same object types continue increasing between dumps, that can provide stronger evidence of object retention.
A practical investigation can therefore use:
Dump A
+
Dump B
+
Application metrics
+
Garbage collection dataThis gives a broader picture than a single snapshot.
Common Production Mistakes
Restarting Before Collecting the Dump
If the goal is to understand the current memory problem, restarting first can destroy useful evidence.
Saving the Dump on a Nearly Full Disk
A large dump can consume substantial storage.
Always check available space first.
Collecting Dumps Without Authorization
Production dumps may contain sensitive application data.
Follow your organization's security and privacy procedures.
Assuming a Large Dump Means a Leak
Memory usage needs to be analyzed in context.
Looking Only at Object Counts
An object can have a high count but relatively small total memory usage.
Look at both count and total size.
Ignoring Native Memory
A managed heap investigation may not explain all process memory usage.
The application can also consume native memory.
Troubleshooting
dotnet-dump Cannot Find the Process
First confirm that the process is a .NET process and that the process ID is correct.
Run:
dotnet-dump psThen verify the target process again.
Dump Collection Fails
Check:
[ ] Process ID
[ ] Tool installation
[ ] Runtime compatibility
[ ] User permissions
[ ] Available disk space
[ ] Output directory permissionsThe Dump Is Too Large
Review whether the selected dump type is appropriate for the problem.
Also check the amount of memory currently used by the process.
Analysis Is Very Slow
Large dumps can require significant CPU, memory, and disk resources during analysis.
Analyze the dump on a machine with enough resources rather than putting additional pressure on the production server.
The Dump Does Not Explain the Problem
A single dump may not be enough.
Collect another dump later and compare the object population and application metrics.
Best Practices
Collect Before Restarting
When possible, capture the evidence before restarting a problematic process.
Use a Dedicated Diagnostic Location
Do not mix dumps with application logs and normal temporary files.
Secure the Dump
Treat production dumps as sensitive data.
Record the Context
For every dump, record:
Application
Process ID
Server
Date and time
Memory usage
CPU usage
Application version
Runtime version
Reason for collectionThis information makes later analysis much easier.
Keep Application Metrics
A dump is much more useful when combined with metrics showing:
Process memory
GC heap size
CPU usage
Request rate
Error rate
GC activityAnalyze Outside Production
Where possible, transfer the dump to a controlled diagnostic environment.
This reduces additional resource pressure on the production application.
Advantages
No application restart is required to capture the current process state.
Production memory problems can be investigated using real application state.
Managed objects can be examined to identify suspicious memory usage.
Multiple dumps can be compared to investigate object growth.
The application can continue running after the collection operation completes.
Disadvantages and Trade-Offs
Dump files can be very large.
Collection can temporarily consume additional resources.
Production dumps can contain sensitive information.
Analysis can require significant CPU and memory.
A single dump may not be enough to identify the root cause.
Native memory issues may require additional diagnostic techniques.
Production Memory Investigation Checklist
Use the following checklist when investigating a memory problem:
[ ] Confirm abnormal memory behavior
[ ] Identify the affected process
[ ] Record application and runtime versions
[ ] Check available disk space
[ ] Verify permission to collect diagnostics
[ ] Collect the dump before restarting
[ ] Store the dump securely
[ ] Record application metrics
[ ] Analyze managed heap usage
[ ] Investigate object retention
[ ] Check for native memory usage
[ ] Compare additional dumps when necessary
[ ] Identify the root cause
[ ] Remove the dump according to retention policy
[ ] Apply and validate the fixConclusion
A memory dump is one of the most useful diagnostic tools for investigating a problematic .NET application without immediately restarting it.
Using dotnet-dump, developers can capture the state of a running process and analyze managed objects, heap usage, threads, and other runtime information afterward.
The most important part is not simply creating the dump. The real value comes from collecting it at the right time, securing it properly, analyzing object retention, and combining the results with application metrics.
When a production application is consuming unusual amounts of memory, restarting may restore service temporarily, but collecting a dump first can preserve the evidence needed to understand what happened.
For production troubleshooting, the practical workflow is straightforward:
Observe
|
v
Confirm abnormal memory usage
|
v
Collect dump without restarting
|
v
Secure and analyze
|
v
Identify retention or allocation problem
|
v
Fix and validateThis approach turns a temporary production symptom into useful diagnostic evidence that can help developers find and fix the underlying memory problem.
Join the conversation! Your thoughts help the community grow.