gpt4 book ai didi

c# - 使用 Autofac 和 EF Core 3.1 的内存泄漏(从 2.2 迁移后)

转载 作者:行者123 更新时间:2023-12-04 12:19:31 26 4
gpt4 key购买 nike

在 Autofac 5.2.0 中使用 EF Core 3.1.5(从 2.2 迁移后)时,我遇到了内存泄漏。我的情况是,在主页上我加载了一些产品列表,每次重新加载页面都会增加 5-10mb 的内存使用量,内存无休止地增加。它永远不会下降。我怀疑我的注册错误(?)或者这是因为 EF Core 中的跟踪行为(?)。我尝试注册我的 MyDbContext如下:

public class DbContextModule<TContext> : Module
where TContext : DbContext
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);

builder
.RegisterType<TContext>()
.WithParameter("options", DbContextOptionsFactory.Get<TContext>())
.InstancePerLifetimeScope();
}
}

public class DbContextOptionsFactory
{
public static DbContextOptions<TContext> Get<TContext>() where TContext : DbContext
{
var confSql = "fake";

var builder = new DbContextOptionsBuilder<TContext>();
DbContextConfigurer.Configure<TContext>(builder, confSql);

return builder.Options;
}
}

public class DbContextConfigurer
{
public static void Configure<TContext>(DbContextOptionsBuilder<TContext> builder, string connectionString) where TContext : DbContext
{
builder.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(3),
errorNumbersToAdd: null);
});
}
}

并在启动文件中:

public void ConfigureContainer(ContainerBuilder builder)
{
...
builder.RegisterModule<DbContextModule<MyDbContext>>();
...
}

我尝试添加 AsSelfExternallyOwned但什么都没有改变。
我也尝试通过 Microsoft DI 注册 DbContext,但没有任何改变。
尝试使用 AddDbContextPoolServiceCollection但仍然没有成功。

使用 EF Core 2.2 时不会出现上述问题。

最佳答案

在通过 DotMemory 进行一些调查后,我发现通过 ServiceProviderCache 有一些内存使用高峰。当我尝试谷歌时 ServiceProviderCache EF Core我发现以下 link .

在我的情况下,问题是我在本地启用控制台日志记录,以便在迁移后更容易地发现 ef core 的问题。 DbContext 看起来像这样:

private readonly ILoggerFactory _loggerFactory;

public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
_loggerFactory = LoggerFactory.Create(b => b.AddConsole());
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);

if (``it is a local run``)
{
optionsBuilder
.UseLoggerFactory(_loggerFactory)
.EnableSensitiveDataLogging();
}
}

有问题的线路是:

public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
_loggerFactory = LoggerFactory.Create(b => b.AddConsole());
}

根据 GitHub 上的答案,每次创建 DbContext 时都会创建记录器,此后不会销毁它。解决方案是使用静态记录器。所以我重构如下:

创建控制台记录器:

public class ConsoleLogger
{
public readonly ILoggerFactory Instance;

public ConsoleLogger()
{
Instance = Microsoft.Extensions.Logging.LoggerFactory.Create(x => x.AddConsole());
}
}

将其注册为单例:

...
builder.RegisterType<ConsoleLogger>().AsSelf().SingleInstance();
...

并在 DbContext 中像这样使用它:

public MyContext(DbContextOptions<MyContext> options, ConsoleLogger consoleLogger)
: base(options) =>
_consoleLogger = consoleLogger;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);

if (``it is a local run``)
{
optionsBuilder
.UseLoggerFactory(_consoleLogger.Instance)
.EnableSensitiveDataLogging();
}
}

由于上面的内存分析图表来自于此:
enter image description here
enter image description here
对此:
enter image description here

关于c# - 使用 Autofac 和 EF Core 3.1 的内存泄漏(从 2.2 迁移后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62402806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com