【问题标题】:Memory Leak with EF Core LoggingEF Core 日志记录的内存泄漏
【发布时间】:2020-11-12 06:25:03
【问题描述】:

我有一个运行最新 Ubuntu LTS 的小型 Digital Ocean droplet(1GB 内存)。我创建了一个小型 DotNet core 3.1 MVC Web 应用程序(+ DotNet Core 身份),它最终达到了任务限制,然后抛出(错误的)OOM 异常。

来自 journalctl 的代表性错误消息:

 Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HM1CRI33JJJE", Request id "0HM1CRI33JJJE:0000043E": An unhandled exception was thrown by the application. System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
 at System.Threading.Thread.StartInternal()
 at Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider..ctor(IOptionsMonitor`1 options)
 at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
 at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
 at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
 at ... (etc)

重新启动时的服务状态:

Site.service - Description here
     Loaded: loaded (/etc/systemd/system/Site.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-07-22 17:08:51 UTC; 48s ago
   Main PID: 656469 (Site)
      Tasks: 21 (limit: 1075)
     Memory: 103.4M
     CGroup: /system.slice/Site.service

存在问题的状态输出:

 Site.service - Description here
     Loaded: loaded (/etc/systemd/system/Site.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-07-22 17:08:51 UTC; 11min ago
   Main PID: 656469 (Site)
      Tasks: 1075 (limit: 1075)
     Memory: 176.1M
     CGroup: /system.slice/Site.service

【问题讨论】:

  • 您能提供更多信息吗?这是什么版本的 .NET Core?你能分享一下你是如何构建/发布/部署它的吗?你是如何配置服务的?你能用 Hello MVC Web 应用程序重现这个问题吗?如果您从应用程序中删除识别堆栈,您能否重现该问题?初始内存使用情况如何?应用程序在运行几个小时后是否会达到某种稳定的内存使用状态,然后才会崩溃?您能否在崩溃前一点点获取应用程序的堆转储?
  • 我没有使用 Hello World 或没有身份堆栈进行复制。在排除其他项目之前,我不确定我是否愿意在这类事情上投入时间......我更新了主帖,回答了你的大部分问题。我不知道如何获取堆转储,但如果你告诉我,我会去做。请注意,该应用程序并没有真正崩溃;它似乎仍在运行,它只是在每个新请求时引发 OOM 异常。我注意到服务状态输出列出了任务,它基本上处于极限。这是预期的吗?
  • @omajid 我已将范围缩小到导致问题的原因(毕竟不是 OOM ——它已经没有任务了)。
  • ....并想通了。错误的日志记录配置导致内存泄漏。

标签: c# linux .net-core out-of-memory


【解决方案1】:

EF Core logging documentation 中所述,如果为每个上下文创建新的日志记录工厂,则会引入内存泄漏。

错误代码:

options.UseSqlite(SqliteDbContext.DataSource)
    .UseLoggerFactory(LoggerFactory.Create(x => x.AddConsole())); // log SQL to console

正确代码:

options.UseSqlite(SqliteDbContext.DataSource)
    .UseLoggerFactory(_loggerFactory) // _loggerFactory is now a static property

代表问题作者添加。

【讨论】:

    【解决方案2】:

    来自https://docs.microsoft.com/en-us/ef/core/logging-events-diagnostics/extensions-logging?tabs=v3

    public static readonly ILoggerFactory MyLoggerFactory
    = LoggerFactory.Create(builder => { builder.AddConsole(); });
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLoggerFactory(MyLoggerFactory)
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFLogging;ConnectRetryCount=0");
    

    【讨论】:

    • 你能解释一下答案吗?如果您要分享帖子,请将其用作参考而非答案。
    猜你喜欢
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多