.NET Core 应用程序进程内存在对象被释放后不会减少

Tao*_*Gil 8 c# memory-management .net-core asp.net-core-2.1

我在 Windows 中运行的 ASP .NET Core 2.1 应用程序遇到问题,该应用程序增加了内存消耗,直到最终崩溃并需要终止进程.NET Core Host。我怀疑原因可能是每小时在后台运行一次的同步任务,并且我已确认禁用它可以解决问题。

我一直在使用 VisualStudio 2019 诊断工具分析此同步任务,并且发现了一个我不理解的行为:

在此输入图像描述

正如你所看到的,我拍摄了 3 张快照:

  1. 同步方法开始时
  2. 结束同步方法
  3. 稍后,一旦我们存在范围

在快照表中,我看到了一个对我来说似乎合乎逻辑的行为:堆大小在任务 (2) 期间显着增长,并且在退出作用域 (3) 时几乎减小到初始大小 (1)。然而,“进程内存”图表显示了一个不同的故事:内存消耗增加了,但它永远不会下降。我已经在发布模式下启动了应用程序dotnet run,并且在查看进程使用的内存时看到了相同的行为.NET Core Host

我有两个问题:

  1. 为什么堆大小和进程内存之间存在这种差异?他们不应该有密切的关系吗?
  2. 这可能是我的网络应用程序崩溃的原因吗?看起来是这样,但内存消耗的增加应该是暂时的,而不是永久性的,直到崩溃为止。我该如何解决它?

备注:我使用一个简单的 .NET Core 控制台应用程序(2.1 和 2.2)重现了相同的行为,没有依赖项,因此它没有链接到 ASP 部分或任何其他库:

internal class Program
{
    private static void Main()
    {
        new Whatever().AllocateSomeStrings();
        // Snapshot3
        Console.ReadKey();
    }
}

public class Whatever
{
    public void AllocateSomeStrings()
    {
        // Snapshot1
        List<string> numbers = Enumerable.Range(0, 50000).Select(n => n.ToString()).ToList();
        // Snapshot2
    }
}
Run Code Online (Sandbox Code Playgroud)

Tao*_*Gil 5

回答我自己的问题:

  1. 堆大小在对象创建时增加,在 GC 时减少。当堆大小增加时,进程内存会增加,但当堆大小减小时,进程内存不一定会减少。该内存可以保留分配给进程,除非其他进程需要它(机器的可用内存变低),从而强制释放它。该进程不由 GC 处理,GC 在进程级别运行。另请参阅:.NET 进程分配的内存何时释放回 Windows
  2. 我发现根本问题是代码中的内存泄漏,一个 while 循环写得不好,修复了崩溃的应用程序。