首页 > 解决方案 > 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”进程。这只会发生在所有生产服务器/虚拟机上,运行相同的应用程序我的笔记本电脑(或任何开发笔记本电脑)不会产生内存泄漏。

开发机器(现在运行 > 2 小时): 在此处输入图像描述

生产服务器(运行约 10 分钟): 在此处输入图像描述

该内存将无限期地堆积,直到服务器内存不足。

那是我用来复制它的代码(再次:在我们的生产系统上,而不是在开发机器上)。在我们的实际应用程序中,实际上是 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 版本/构建所误导。

标签: c#windowsasp.net-corememory-leaks

解决方案


我向微软报告了这个错误,它已经被修复了。

... 2021 年 5 月 Windows Server 2016 更新

2021 年 5 月的 Windows Server 2016 更新 (KB5003197) 中包含一个修复程序,但隐藏在功能标志后面。激活它

  1. 安装 KB5003197
  2. 添加此注册表项:reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\Microsoft\FeatureManagement\Overrides /v 1402424459 /t REG_DWORD /d 1 /f
  3. 重启系统

... 2021 年 6 月 Windows Server 更新:

在不使用注册表项的情况下,此修复程序应该在 June-Update 中处于活动状态,但我尚未对此进行测试。


推荐阅读