我有一个小的Digital Ocean液滴(1GB的RAM(运行最新的Ubuntu LTS。我创建了一个小的DotNet核心3.1MVC web应用程序(+DotNet内核标识(,它最终达到了任务限制,然后抛出(错误的(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
如EF Core日志记录文档中所示,如果为每个上下文创建新的日志记录工厂,则可能会引入内存泄漏。
错误代码:
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
代表问题作者添加
来自https://learn.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");