Skip to content

Memory leak with Sentry.Profiling 6.6.0 on Linux: TraceEvent call-stack/method index tables accumulate unboundedly under traffic (~0.6 GB/day to OOM) #5469

Description

@therickfactr

Package

Sentry.Profiling

.NET Flavor

.NET

.NET Version

8.0

OS

Linux

SDK Version

6.6.0 (Sentry.AspNetCore 6.6.0 + Sentry.Profiling 6.6.0)

Self-Hosted Sentry Version

No response (SaaS)

Steps to Reproduce

  1. ASP.NET Core service on Linux x64 (Rocky 9, kernel 5.14), 8 GB VM, systemd-hosted, builder.WebHost.UseSentry(...) with options.AddProfilingIntegration().
  2. TracesSampleRate: 0.1, ProfilesSampleRate: 0.1.
  3. Run under real production traffic (an idle instance does not reproduce — sampled transactions drive it).
  4. Watch process RSS over days.

Expected Result

Profiling overhead reaches a bounded steady state.

Actual Result

RSS grows ~0.6 GB/day under steady traffic until kernel OOM-kill at ~6.1 GB anon RSS after ~8 days of uptime. Growth rate is traffic-proportional (~100 MiB/hr at evening peak, less overnight).

dotnet-gcdump on the live process (t+5.5 h after a restart, working set 1581 MiB and climbing) shows 478 MB live heap / 8.67 M objects, and the top retained large types are all Microsoft.Diagnostics.Tracing (TraceEvent) bookkeeping:

   Object Bytes     Count  Type
     35,087,256         1  CallStackInfo[]  [Microsoft.Diagnostics.Tracing.TraceEvent.dll]
     35,087,256         1  System.Collections.Generic.List<Microsoft.Diagnostics.Tracing.Etlx.CallStackIndex>[]
      2,548,664         1  MethodInfo[]  [Microsoft.Diagnostics.Tracing.TraceEvent.dll]
      2,548,536         1  CodeAddressInfo[]  [Microsoft.Diagnostics.Tracing.TraceEvent.dll]
      2,172,576         1  Entry<System.Int64,TraceCodeAddresses+ILMapIndex>[]
      1,810,368         1  Entry<System.UInt64,CodeAddressIndex>[]
      1,048,600         1  MethodLoadUnloadVerboseTraceData[]  [TraceEvent]
        876,536         1  TraceMethod[]  [TraceEvent]
        849,528         1  ILToNativeMap[]  [TraceEvent]
        424,776         1  CodeAddressIndex[]  [TraceEvent]
        161,984         1  Entry<System.Int32,EventPipe.StackCache+StackMarker>[]

(These are the >100 KB single arrays; the remaining growth is millions of small entries in the same structures.)

A/B on the identical build: set ProfilesSampleRate: 0 and restart → t+10 h working set 477 MiB and falling; gcdump shows 31 MB live / 470 k objects with zero TraceEvent types. Leak fully cured by disabling profiling alone (tracing, logs, error reporting all left enabled).

Analysis

The continuous in-process EventPipe/TraceEvent session backing transaction profiling accumulates call-stack, code-address, and IL-map index tables (CallStackInfo, TraceCodeAddresses maps, ILToNativeMap, StackCache) for the life of the session, proportional to the diversity/volume of sampled stacks. They are never trimmed.

Related history — all distinct mechanisms, and all already present in 6.6.0:

As far as I can tell this steady-state TraceEvent index accumulation has no existing open or closed issue.

Happy to attach both full gcdump type histograms (with-profiling vs without) if useful.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status
    Waiting for: Product Owner

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions