c# - Windows 10 (1607) / Windows Server 2016 上的 ASP.NET Core ILogger 内存泄漏
问题描述
TL;博士
我现在很确定在 Windows 10(版本 1607)和 Windows Server 2016 中的 conhost 进程中存在内存泄漏,而在 Windows Server 2012 R2 中不存在并且在 Windows 10(版本 1809+)和视窗服务器 2019。
我找不到对该错误的任何官方参考,如果有人可以为我指出这一点,我将不胜感激。
很长的故事
我目前正在调查我们的(自托管)ASP.NET Core 应用程序中的内存泄漏,这会导致高内存使用,而不是 .exe 本身,而是相应的“conhost”进程。这只会发生在所有生产服务器/虚拟机上,运行相同的应用程序我的笔记本电脑(或任何开发笔记本电脑)不会产生内存泄漏。
该内存将无限期地堆积,直到服务器内存不足。
那是我用来复制它的代码(再次:在我们的生产系统上,而不是在开发机器上)。在我们的实际应用程序中,实际上是 EFCore 日志记录导致问题(EFCore 也使用 ASP.NET Core Loggers):
public class LoggingBackgroundService : BackgroundService
{
private readonly ILogger<LoggingBackgroundService> logger;
public LoggingBackgroundService(ILogger<LoggingBackgroundService> logger)
{
this.logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
for (var i = 0; i < 10; i++)
{
Task.Run(() => RunBackgroundThread(stoppingToken));
}
await Task.Delay(Timeout.Infinite, stoppingToken);
}
private async Task RunBackgroundThread(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
for (var i = 0; i < 1000; i++)
{
logger.LogInformation(GetLogMessage());
//Console.WriteLine(GetLogMessage());
}
await Task.Delay(1000);
}
}
private string GetLogMessage()
{
return DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.ffff");
}
}
使用Console.WriteLine()
而不是记录器可以工作并且不会产生内存泄漏。再一次,该代码在开发机器上运行良好。
我们正在使用 .NET Core 3.1。谁能解释这里发生了什么?
编辑:我的测试系统目前位于 ~9 GB RAM,所以也许有一个限制,但无论如何在“conhost”进程上花费的 RAM 太多了。
我还尝试使用 DebugDiag 来分析内存转储,但它显示的堆栈跟踪并不能真正帮助我(但还能期待什么?):
LeakTrack+13277
ConhostV2!MergeAttrStrings+b8
ConhostV2!WriteCharsLegacy+a9c
ConhostV2!DoSrvWriteConsole+4ea
ConhostV2!ConsoleIoThread+36b
kernel32!BaseThreadInitThunk+14
ntdll!RtlUserThreadStart+21
我对虚拟机只有基本的了解,但目前看起来它只发生在 VMWare ESX (?) 系统中?我不再认为 VMWare 是导致问题的原因,而是被不同的 Windows 10 版本/构建所误导。
- [泄漏] Windows Server 2016(在 VMWare ESX 上)
- [泄漏] Windows 10、1607(在 VMWare ESX 上)
- [泄漏] Windows 10、1607(在 Azure 上)
- [泄露] Windows Server 2016(在 Azure 上)
- [泄露] Windows Server 2016(在 AWS 上)
- [泄漏] Windows 10、1607(在 Hyper-V 上)
- [泄漏] Windows Server 2016(在 Hyper-V 上)
- [无泄漏] Windows 10、1909(在 VMWare 工作站上)
- [无泄漏] Windows Server 2019(在 Azure 上)
- [无泄漏] Windows 10、1909(在 Hyper-V 上)
- [无泄漏] Windows Server 2019(在 Hyper-V 上)
- [无泄漏] Windows 10、1809(在硬件上)
解决方案
我向微软报告了这个错误,它已经被修复了。
... 2021 年 5 月 Windows Server 2016 更新:
2021 年 5 月的 Windows Server 2016 更新 (KB5003197) 中包含一个修复程序,但隐藏在功能标志后面。激活它
- 安装 KB5003197
- 添加此注册表项:
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\Microsoft\FeatureManagement\Overrides /v 1402424459 /t REG_DWORD /d 1 /f
- 重启系统
... 2021 年 6 月 Windows Server 更新:
在不使用注册表项的情况下,此修复程序应该在 June-Update 中处于活动状态,但我尚未对此进行测试。
推荐阅读
- java - java.net.SocketException:对等方重置连接。在自定义抽搐机器人
- python - 如何在不使用排序功能的情况下在 python 中排序
- swift - 使用 Decodable 将空 JSON 字符串值解码为 nil
- json - JSON模型中使用枚举类型访问结构属性的语法
- r - SVM 交叉验证问题 - 表中的错误(testingsvmmodel,testing):所有参数必须具有相同的长度
- eclipse - Tomcat localhost failed to start
- mysql - SQL 中的非包含 BETWEEN
- python - AttributeError:“int”对象没有属性“keys”
- javascript - 从代码更改输入模型时出现错误模式
- c - 在一个函数中删除所有二叉搜索树