【问题标题】:Entity Framework core possible memory leak in web applicationWeb 应用程序中的实体框架核心可能存在内存泄漏
【发布时间】:2018-08-07 17:50:10
【问题描述】:

我在我的 ASP.NET MVC Core (v1) 应用程序中使用 EF Core。而且我注意到,在将我的应用程序托管在生产环境中进行测试时,IIS 服务器通常会由于达到其内存限制而非常频繁地回收。

我想验证我在我的应用程序中使用dbContext 的方式是否有效,并且没有在后台造成任何内存泄漏。我在 SO 上阅读了一些类似的帖子,人们建议在使用上下文对象后对其进行处置。

但我通过依赖注入使用它,如下所示。

Startup.cs 类 sn-p:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<Context>();
}

Context.cs 类 sn-p:

    public class Context : IdentityDbContext<ApplicationUser> 
    {
        private IConfigurationRoot _config;
        private IHttpContextAccessor _HttpContextAccessor;

        public Context(IConfigurationRoot config, DbContextOptions options, IHttpContextAccessor HttpContextAccessor)
            : base(options)
        {
            _config = config;
            _HttpContextAccessor = HttpContextAccessor;
        }

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

            optionsBuilder.UseSqlServer(_config["ConnectionStrings:ContextConnection"]);
        }
}

services.AddDbContext&lt;Context&gt; 是否注入了上下文的共享实例,这会导致所有查询的实体随着时间的推移而累积,从而占用内存?

编辑:我还有以下几个单例实例,如下所示:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddSingleton<ILoggerService, LoggerService>();

services.AddSingleton<IEmailSender, EmailSender>();

谢谢!

【问题讨论】:

  • AddDbContext 添加一个 Scoped 实例,所以它是每个请求。为什么要注入 IHttpContextAccessor 而不是只在 AddDbContext 上传递配置?
  • 嗨,卡米洛!我这样做是因为我也在使用名为 entity framework plus (entityframework-plus.net) 的库进行一些后台审计日志记录,因此需要一些进一步的信息来执行一些后台审计日志记录。
  • 因此,由于这是一个作用域实例,这意味着我的 EF 实现确实没有导致内存泄漏。有什么方法可以测量我的开发环境中内存在哪里用完?谢谢!
  • 这不是一件容易的事,不,您需要对应用程序进行分析以查看它可能出错的地方。不久前,我在注入 IConfiguration 时回答了一个内存问题的问题,就像你正在做的那样 (_config = config;),所以也要检查一下
  • Camilo,我更新了我的帖子,在我的代码中还包含了一些额外的单例定义。是否建议将此类项目更改为作用域/瞬态?

标签: c# dependency-injection asp.net-core-mvc entity-framework-core


【解决方案1】:

在我的例子中,在动作过滤器和一些中间件中,我使用了一个 IServiceProvider,它使用 services.BuildServiceProvider() 创建,如下所示:

public class DependencyManager{
    static class IServiceProvider ServiceProvider{ get;set;}
}
public class SomeMiddleware{
    public void SomeMethod(){
         var someServiceInstance = DependencyManager.ServiceProvider.GetService<SomeService>();
    }
}

因此,为注入此服务而创建的所有作用域对象都不会链接到任何请求,并且不会在请求结束时释放。我在 HttpContext 下使用 RequestServices 解决了这个问题:

public class SomeMiddleware{
    public void SomeMethod{
        var someServiceInstance = context.RequestServices.GetService<SomeService>()
    }
}

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    相关资源
    最近更新 更多