Приложение .NET Core Процессная память не уменьшается после освобождения объектов - PullRequest
0 голосов
/ 27 сентября 2019

У меня проблемы с приложением ASP .NET Core 2.1, работающим в Windows, которое увеличивает потребление памяти до тех пор, пока, наконец, не выйдет из строя и не потребует завершения процесса .NET Core Host.Я подозревал, что причиной может быть задача синхронизации, выполняемая в фоновом режиме один раз в час, и я подтвердил, что ее отключение решает проблему.

Я профилировал эту задачу синхронизации с помощью средств диагностики VisualStudio 2019, и яЯ обнаружил поведение, которое я не понимаю:

enter image description here

Как видите, я сделал 3 снимка:

  1. В начале метода синхронизации
  2. В конце метода синхронизации
  3. Чуть позже, когда мы уже создали область действия

ВТаблица снимков Я вижу поведение, которое кажется мне логичным: размер кучи значительно увеличивается во время выполнения задачи (2) и уменьшается почти до исходного размера (1) при выходе из области действия (3).Однако диаграмма «Память процесса» показывает другую историю: увеличение потребления памяти есть, но оно никогда не снижается.Я запустил приложение с dotnet run в режиме Release, и я вижу то же поведение при просмотре памяти, используемой процессом .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
    }
}
...