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:
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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With