EF核心日志记录的内存泄漏(已解决)

时间:2020-07-22 16:21:29

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

我有一个小的Digital Ocean小滴(1GB RAM)运行最新的Ubuntu LTS。我创建了一个小的DotNet core 3.1 MVC Web应用程序(带有DotNet Core标识),最终达到任务限制,然后抛出(错误的)OOM异常。

journalctl的代表性错误消息:

ERROR 1054 (42S22): Unknown column '’root’' in 'where clause'

全新服务状态:

 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

解决方案

我是个白痴。如EF Core logging documentation中所述,如果为每个上下文创建一个新的日志记录工厂,则可能导致内存泄漏。

错误代码:

 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

正确的代码:

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

2 个答案:

答案 0 :(得分:0)

来自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");

答案 1 :(得分:0)

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

代表问题作者添加。