Search code examples
.netmemory-leaksopenshiftdistributed-tracing

Potential memory leak with use of ActivitySource


We are suspecting (or have concluded) a memory leak in a dotnet 6 application running in an Enterprise OpenShift cluster with limited permissions. The reason for us being suspicious is the graph here which shows a increasing memory usage across our containers. Even though the GC helps a bit we have seen that the containers gets an out of memory exception when they have been running for a long time. Memory usage image

I have tried to run dotnet-dump commands to get a dump of memory. Due to restrictions in the cluster that has not been a possible solution for us. I cannot manipulate with the docker run command in the cluster.

Therefore we have tried to investigate the code and I found from various Stack Overflow posts a potential issue. We are using static variables in a Transient service.

public class MyTransientService: IMyTransientService
{
    private readonly IOtherService _otherService;
    private static readonly ActivitySource ActivitySource = new(nameof(MyTransientService));
}

public async Task<SomeClass> GetTransactionsFromMeniga(SomeOtherClass testObj)
{
    using var thisActivity = ActivitySource.StartActivity("New activity");
}

As far as I understand static variables are never GC'ed, hence every time this service will be instantiated a new ActivitySource will be created and never cleaned up.`

The implementation of ActivitySource is from Microsoft's guide to distributed tracing.

How do you use ActivitySource in transient services so you avoid using static variables? I can think of a solution where I could inject a singleton service with the various ActivitySource's. But are they thread safe?

So to summarize: Are there any advice for using ActivitySource in a Transient service?


Solution

  • I can confirm that using a static variable in a transient class will cause this type of memory issue as static variables will not be destroyed with the transient class instance.