Skip to content

Address memory consumption when Tracing is enabled with OTel #3550

Closed

Description

@jamescrosswell

We've had multiple users report either memory leaks or high memory consumption when tracing is enabled in the SDK. Conversations with users exchanging logs etc. has not led to a successful resolution of the problems and none of the SDK maintainers has been able to reproduce a scenario that results in a memory leak.

We really need some way to be able to reproduce the problem to be able to investigate and find a solution.

Related Issues

Activity

  1. ericsampson commented on Aug 22, 2024

    @ericsampson
    Contributor

    Maybe Julian from the other issue would be willing to do some experimenting/data gathering, since it seems like they have a good repro situation…

  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Aug 22, 2024
  3. jamescrosswell commented on Aug 22, 2024

    @jamescrosswell
    CollaboratorAuthor

    Maybe Julian from the other issue would be willing to do some experimenting/data gathering, since it seems like they have a good repro situation…

    cc: @Julian-Robinson @cliedeman

  4. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Aug 22, 2024
  5. jamescrosswell commented on Nov 25, 2024

    @jamescrosswell
    CollaboratorAuthor

    Closing this as we're unable to reproduce. If anyone is able to provide a minimal reproducible example, we can reopen and look into this again.

  6. 13 remaining items

  7. danpaul88 commented on May 4, 2026

    @danpaul88

    Looks like dotMemory is now able to open the dump files from the net10.0 containers, so I can more clearly see what's going on again.

    Using the following versions of Sentry and OpenTelemetry

    Image Image

    We still see the memory usage issue. I've taken a memory dump from one of our problematic pods, which currently reports about 1.6gb of memory consumption.

    Image

    However, interestingly, dotMemory shows that only ~600mb of this is actually used by dotnet... around 90% of which is retained by the SentrySpanProcessor

    Image

    A lot of the memory usage seems to stem from very high fragmentation, such as this example of a 33mb pinned object heap (one of several pinned object heaps) with only 4% utilisation

    EDIT: Correction - it's actually in a Large Object Heap, which makes sense. I think DATAS affects how dotMemory sees the LOH and causes it to lump it in with the POH.

    Image

    Which just contains a concurrent dictionary of ActivitySpanId to ISpan mappings

    Image

    Because this object is pinned it's holding the entire 33mb pinned object heap in memory, when it could otherwise be released back to the OS - this seems to be at least one of the causes of the large amount of memory consumption I'm seeing on our pods.

    There is definitely a lack of heap compaction occurring on the pod I've sampled since there are around 100 Gen2 heaps of 4mb each, which is definitely contributing to the total memory usage, but I still wouldn't expect to see over 550mb of memory being directly retained by the SentrySpanProcessor

  8. danpaul88 commented on May 4, 2026

    @danpaul88

    Looking at an example of one of the retained spans, I see it has zero spans in _spans, started at 2026-04-30​T05:29:32.691Z (based on the backing field for StartTimestamp) and was for an Microsoft.AspNetCore.Hosting.HttpRequestIn activity

    Image

    Given my memory dump was taken on 2026-05-04, it seems quite unlikely that an activity that started 4 days ago is still ongoing with 0 child spans - I wonder if somehow spans are not being cleaned up with the associated activity ends, perhaps due to sampling decisions made by OpenTelemetry? It would be odd that we don't observe the same behaviour across all of our clusters if that is the case though

    Looking in _contexts I see that IsSampled appears to have no value, but I'm not sure enough about the internal data structures in Sentry to know if this is relevant or not

    Image

    Let me know if there's anything specific I can dig out of the memory dump that could help

  9. danpaul88 commented on May 4, 2026

    @danpaul88

    I'm wondering if it might be related to;

    #3198

    This works around an OTel bug whereby OnEnd isn't called if a span is filtered by OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter

    Looking at the source for PruneFilteredSpans (which that PR introduced), it looks like it tries to get the Activity associated with the span via a weak reference and, if that activity is {Recorded: false, IsAllDataRequested: false}, it prunes it from the map.

    What it doesn't seem to handle, if I'm reading it right, is the case where the associated Activity has already been GC'd before PruneFilteredSpans next gets called. Since PruningInterval is 5 seconds a filtered activity lasting less than 5 seconds could easily have already been GC'd before the next pruning occurs. In this case the weak reference cannot be resolved, can never match the condition {Recorded: false, IsAllDataRequested: false}, and thus can never get pruned

    I may be misunderstanding what GetFused<Activity> is doing mind you

    @jamescrosswell what do you think?

  10. jamescrosswell commented on May 4, 2026

    @jamescrosswell
    CollaboratorAuthor

    @jamescrosswell what do you think?

    @danpaul88 that sounds possible yeah... the condition on this line basically:

    if (activity is { Recorded: false, IsAllDataRequested: false })

    ... will only match if the associated Activity is not null.

    We could change that to:

    if (activity is null || activity is { Recorded: false, IsAllDataRequested: false }) 

    That way it would filter and remove any Activities that had already been cleaned up by the GC.

    I think we'd need to update this logic as well:

    spanTracer.IsFiltered = () => spanTracer.GetFused<Activity>() is { IsAllDataRequested: false, Recorded: false };

    That one is less about memory consumption and more about the accuracy of the visual representation in the trace, but still.

  11. linear-code commented on May 4, 2026

    @linear-code
  12. jamescrosswell commented on May 5, 2026

    @jamescrosswell
    CollaboratorAuthor

    @danpaul88 fix coming in the 6.5.0 release.

  13. Flash0ver commented on May 5, 2026

    @Flash0ver
    Contributor

    Thank you very much, @danpaul88, for your detailed analysis!

  14. changed the title [-]Address memory consumption when Tracing is enabled **Cannot reproduce***[/-] [+]Address memory consumption when Tracing is enabled with OTel[/+] on May 5, 2026
  15. added
    .NETPull requests that update .net code
    on May 5, 2026
  16. danpaul88 commented on May 5, 2026

    @danpaul88

    @jamescrosswell fantastic - thanks for the quick fix. I'll get our services updated once it's out and will report back to confirm

    @Flash0ver no problem at all 👍 good to get to the bottom of it

  17. Flash0ver commented on May 5, 2026

    @Flash0ver
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions