Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak with EF Core Logging

I have a small Digital Ocean droplet (1GB of RAM) running the most current Ubuntu LTS. I created a small DotNet core 3.1 MVC web app (+ DotNet Core identity) that eventually hits a task limit and then throws (erroneous) OOM exceptions.

Representative Error messages from 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)

Service status on fresh start:

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

Status output with problem active:

 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
like image 674
jstur Avatar asked Nov 06 '22 06:11

jstur


1 Answers

As indicated in the EF Core logging documentation, a memory leak can be introduced if a new logging factory is created for each context.

Bad code:

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

Correct code:

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

Added on behalf of the question author.

like image 109
Dharman Avatar answered Nov 15 '22 05:11

Dharman