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.
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?
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.