Memory.Introspect

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.

© 2026 Memory.Introspect. All rights reserved.