Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceProvider not releasing memory for transient EF context

I have a windows service on .NET 4.6.2 where I register a EF6 DbContext as Transient using the .NET ServiceProvider (System.IServiceProvider interface). The service starts using around 30mb of memory, and after a day reaches 1Gb.

Running a profiler on the process tells me hundreds of thousands of DbContext objects waiting to be released, even though I'm disposing the context after each use.

Here is a sample of the code:

// registration
var services = new ServiceCollection();
services.AddTransient(sp => new ServiceDbContext(connectionString));
var serviceProvider = services.BuildServiceProvider();

// use
using (var ctx = serviceProvider.GetRequiredService<ServiceDbContext>()) { ... }

Adding AsNoTracking to queries reduced the memory usage, but contexts are still held in memory forever. It appears there isn't any release method for ServiceProvider.

Here is a sample object tree by running the service for a few minutes, then letting it idle for a few more minutes. 4838 is the number of times I instantiated the context. Note I forced GC after a few minutes idle before taking this snaptshot:

enter image description here

Is there anything else I should do to release the context other than disposing it? Or is this some limitation of the built in service provider?

like image 446
Natan Avatar asked Feb 08 '17 12:02

Natan


1 Answers

Ok, this looks like a bug in the current implementation of the ServiceProvider that for some reason tracks disposables in the root context.

https://github.com/aspnet/DependencyInjection/issues/456

like image 149
Natan Avatar answered Nov 15 '22 13:11

Natan