Memory.Introspect

Process dumps

DumpAsync writes a full process dump — the equivalent of dotnet-dump collect. Unlike .gcdump, the output contains every byte of the process's memory: managed objects, unmanaged buffers, thread stacks, register state, loaded modules.

Use it when you need to:

  • Diagnose a crash or hang where the managed view isn't enough.
  • Inspect unmanaged memory accessed via P/Invoke.
  • Open the snapshot in WinDbg or dotnet-dump analyze.

Capturing

using Memory.Introspect;
using static Memory.Introspect.Dumper;

int pid = Process.GetCurrentProcess().Id;

var introspector = MemoryIntrospector.Create();
int rc = await introspector.DumpAsync(
    pid,
    targetPath: $"crash-{DateTimeOffset.UtcNow:yyyyMMdd-HHmmss}.dmp",
    collectionType: CollectionType.Heap);

DumpAsync returns the same status code that dotnet-dump collect would — non-zero indicates failure.

Collection types

CollectionType mirrors the equivalent option in dotnet-dump. It trades dump completeness against file size:

Value Approximate size What's included
Mini Small (~50 MB) Thread stacks, loaded modules, minimal memory.
Heap Medium (proportional to working set) The full managed heap plus everything Mini has.
Triage Small Trimmed dump optimised for crash triage.
Full Large (full address space) Everything. Useful when you need unmanaged memory too.

For most ".NET memory leak" investigations, Heap is the right balance — large enough to be analysable, small enough to ship to a colleague.

When to use this vs. CollectMemoryGraphAsync

Question API
Why is the managed heap growing? Who holds what? CollectMemoryGraphAsync (cheaper, smaller).
The process crashed / hangs in unmanaged code. DumpAsync.
I need to inspect a specific thread's stack. DumpAsync.
I need both managed and unmanaged context. DumpAsync.

DumpAsync is more expensive — it freezes the process for the duration of the capture and produces large files. Reach for CollectMemoryGraphAsync first; escalate to DumpAsync only when you need what it provides.

Capturing another process

DumpAsync accepts any PID you have permission to reach. On Linux/macOS that usually means the same user; on Windows, matching ACLs on the diagnostics pipe.

int targetPid = int.Parse(args[0]);
await introspector.DumpAsync(targetPid, $"target-{targetPid}.dmp", CollectionType.Heap);

If permission is denied, the call throws — wrap in try/catch if the surrounding workflow needs to be tolerant.

Common pitfalls

Process dumps are large

CollectionType.Full against a 4 GB process produces a 4 GB file. Plan storage and transfer time accordingly — .gcdump is usually a better starting point.

Cancel a dump cleanly

DumpAsync doesn't accept a CancellationToken because the underlying tool is a single one-shot operation. If you need to cancel, run it in a task you can drop — but the runtime continues until the dump finishes regardless.

Analyzing the result

Open the dump in:

  • dotnet-dump analyze CLI — the standard cross-platform analyser.
  • WinDbg / WinDbg Preview — on Windows, for richer interactive analysis.
  • Visual StudioFile → Open → Dump File.

For the canonical workflow, see Microsoft's "Analyze a memory dump" docs.

© 2026 Memory.Introspect. All rights reserved.