Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ServiceProviderCache keeps initially created IServiceProvider indefinitely #27169

Closed
PawelGerr opened this issue Jan 11, 2022 · 1 comment
Closed
Labels
area-dbcontext closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Milestone

Comments

@PawelGerr
Copy link

The ServiceProviderCache uses instances of IDbContextOptions as keys for the internal ConcurrentDictionary. A key of type IDbContextOptions contains, among other things, the extension CoreOptionsExtension which has an _applicationServiceProvider.

After creation and disposal of the first DbContext the ServiceProviderCache keeps the IDbContextOptions incl. the (disposed) IServiceProvider, which keeps all IDisposable instances in it. One of the disposables is the DbContext itself.

The result is that the reference _applicationServiceProvider prevents GC to reclaim the memory.

image

Repro

Program.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.DependencyInjection;

var rootServiceProvider = new ServiceCollection()
                          .AddDbContext<DemoDbContext>(builder =>
                                 builder.UseSqlServer("server=localhost;database=demo;integrated security=true"))
                          .BuildServiceProvider();

CreateAndDisposeContext(rootServiceProvider);

var cache = ServiceProviderCache.Instance;

static void CreateAndDisposeContext(IServiceProvider rootServiceProvider)
{
   using var scope = rootServiceProvider.CreateScope();

   scope.ServiceProvider.GetRequiredService<DemoDbContext>();
}


public class DemoDbContext : DbContext
{
   public DemoDbContext(DbContextOptions<DemoDbContext> options)
      : base(options)
   {
   }
}

csproj file

<Project Sdk="Microsoft.NET.Sdk">

   <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>net6.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
   </PropertyGroup>

   <ItemGroup>
     <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
   </ItemGroup>

</Project>

Provider and version information

EF Core version: 6.0.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
Operating system: Windows 10 x64
IDE: Rider 2021.3.2

@PawelGerr PawelGerr changed the title ServiceProviderCache keep initialy created IServiceProvider indefinitely ServiceProviderCache keeps initially created IServiceProvider indefinitely Jan 11, 2022
@ajcvickers
Copy link
Contributor

@AndriySvyryd This looks like a consequence of no longer just using the hash. I now remember that this was why we did it the hash way in the first place!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dbcontext closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Projects
None yet
Development

No branches or pull requests

3 participants