Configuration
MemoryIntrospectorOptions is the single configuration surface. Every option has a sensible default; the table below explains what each one does and when to change it.
var introspector = MemoryIntrospector.Create(new MemoryIntrospectorOptions
{
Logger = logger,
Verbose = true,
Timeout = TimeSpan.FromMinutes(5),
ExpectLargeGraph = true,
MaxNodeCount = 50_000_000,
CircularBufferSizeInMB = 2048,
DiagnosticPort = null,
SamplingExcludedModules = new[] { "Memory.Introspect" },
LogLevel = LogLevel.Information,
});
Logging
| Option | Default | Effect |
|---|---|---|
Logger |
null |
An ILogger that receives library output. null discards. |
LogLevel |
LogLevel.Information |
Level used for messages written through the logger. |
Verbose |
true |
Enables detailed protocol diagnostics — handshake, EventPipe setup, graph progress. |
For production, set Verbose = false to keep log noise down. Re-enable when debugging a captured failure.
Timeout
| Option | Default | Effect |
|---|---|---|
Timeout |
30s |
Maximum duration of the EventPipe session. Clamped to a minimum of 30 s. |
The 30-second floor exists because shorter timeouts rarely complete a capture against a non-trivial heap. For large heaps, raise it generously — there's no harm in setting Timeout = TimeSpan.FromMinutes(10) on a server with multi-GB heaps. The capture finishes as soon as the heap walk completes; the timeout only kicks in when something is wrong.
A CancellationToken passed to CollectMemoryGraphAsync overrides the timeout — use it when you need precise cancellation.
Large heaps
| Option | Default | Effect |
|---|---|---|
ExpectLargeGraph |
false |
Tells MemoryGraph to allocate internal data structures for millions of nodes upfront. |
MaxNodeCount |
10_000_000 |
Hard ceiling on the number of nodes in the graph. Captures exceeding this fail. |
CircularBufferSizeInMB |
1024 |
Size of the EventPipe ring buffer used to stream events from the runtime. |
For heaps with more than a few million objects:
ExpectLargeGraph = true,
MaxNodeCount = 50_000_000,
CircularBufferSizeInMB = 4096,
Timeout = TimeSpan.FromMinutes(15),
The buffer size matters because EventPipe drops events if your consumer can't keep up. For long captures against very busy processes, a small buffer leads to silently missing GC events and an incomplete graph.
Diagnostic ports
| Option | Default | Effect |
|---|---|---|
DiagnosticPort |
null |
A named diagnostic pipe to use instead of the per-PID default. |
The runtime exposes a default diagnostics pipe at startup. When you set the DOTNET_DiagnosticPorts environment variable in the target process, it also listens on additional named pipes — which Memory.Introspect can talk to via DiagnosticPort. This is the standard pattern for sidecar diagnostics. See Remote diagnostic ports.
Sampling profile
| Option | Default | Effect |
|---|---|---|
SamplingExcludedModules |
SamplingProfiler.DefaultExcludedModules |
Assembly simple names whose frames are filtered out of TopMethods. |
Use this to keep your own scaffolding out of CPU profiles. Pass Array.Empty<string>() to disable filtering.
Reasonable defaults by scenario
Production memory-leak guard (self-capture)
new MemoryIntrospectorOptions
{
Logger = logger,
Verbose = false,
Timeout = TimeSpan.FromMinutes(2),
LogLevel = LogLevel.Warning,
}
Capture only when a threshold is crossed; log only the outcome.
Production CPU profile (self-capture)
new MemoryIntrospectorOptions
{
Logger = logger,
Verbose = false,
SamplingExcludedModules = new[]
{
"Memory.Introspect",
"Microsoft.Diagnostics.NETCore.Client",
"Microsoft.Extensions.Logging",
"System.Private.CoreLib",
},
}
Schedule with BackgroundService and a generous interval.
Large-heap analysis (e.g. 16 GB managed)
new MemoryIntrospectorOptions
{
Logger = logger,
Verbose = true,
Timeout = TimeSpan.FromMinutes(20),
ExpectLargeGraph = true,
MaxNodeCount = 100_000_000,
CircularBufferSizeInMB = 8192,
}
Expect the capture to take minutes and produce a .gcdump proportional to the live heap.
Sidecar / cross-process
new MemoryIntrospectorOptions
{
Logger = logger,
DiagnosticPort = "/tmp/dotnet-diagnostic-app",
Timeout = TimeSpan.FromMinutes(5),
}
Requires DOTNET_DiagnosticPorts to be set in the target process — see Remote diagnostic ports.