Почему не используется куча памяти после GC в CLR? - PullRequest
0 голосов
/ 13 июня 2019

Я написал тестовую программу для изучения того, как работает GC в ASP.NET Core.

Программа работала в докере с ограничением памяти, установленным ниже 9 МБ.

Я обнаружил, что программа будет убита Docker из-за нехватки памяти, которую Docker ограничил.

Я думал, что GC не сработал. Но когда я записал информацию о GC в программе, я обнаружил, что это происходит слишком много раз, когда объем памяти кучи не уменьшается. Почему?

Версия ASP.NET Core - 2.2. Я уже попробовал последнюю версию 3.0-preview5, работает отлично. Я думаю, что оптимизация GC в .NET Core 3.0 приводит к другим последствиям. Но я не могу понять, почему.

Вот некоторые сведения об оптимизации GC в Core3.0.

PR: https://github.com/dotnet/coreclr/pull/22180/files

Блог: https://devblogs.microsoft.com/dotnet/running-with-server-gc-in-a-small-container-scenario-part-1-hard-limit-for-the-gc-heap/

Мой код ниже:

            if (GCSettings.IsServerGC == true)
                    Console.WriteLine("Server GC");
            else
                    Console.WriteLine("GC WorkStationGC");
            byte[] buffer;
            for (int i = 0; i <= 100; i++)
            {
                buffer = new byte[ 1024 * 1024];


                Console.WriteLine($"allocate number {i+1} objet ");

                var num = GC.CollectionCount(0);
                var usedMemory = GC.GetTotalMemory(false) /1024 /1024;

                Console.WriteLine($"heap use {usedMemory} mb");
                Console.WriteLine($"GC occurs {num} times");
                Thread.Sleep(TimeSpan.FromSeconds(5));
           }

команда запуска docker:

docker run -m 9mb -t xxx

результат с .NET Core2.2:

GC WorkStationGC
allocate number 1 objet 
heap use 1 mb
GC occurs 0 times
allocate number 2 objet 
heap use 2 mb
GC occurs 0 times
allocate number 3 objet 
heap use 3 mb
GC occurs 0 times
allocate number 4 objet 
heap use 1 mb
GC occurs 1 times
allocate number 5 objet 
heap use 2 mb
GC occurs 1 times
allocate number 6 objet 
heap use 3 mb
GC occurs 1 times
allocate number 7 objet 
heap use 4 mb
GC occurs 2 times
allocate number 8 objet 
heap use 5 mb
GC occurs 3 times
allocate number 9 objet 
heap use 6 mb
GC occurs 4 times
allocate number 10 objet 
heap use 7 mb
GC occurs 5 times
allocate number 11 objet 
heap use 8 mb
GC occurs 6 times
allocate number 12 objet 
heap use 9 mb
GC occurs 7 times
root@server:~/ConsoleApp3# 

Выход из программы, когда объем выделенной памяти превышает 9 МБ. Пока GC происходит 7 раз. Кажется, что GC вообще не работает.

Результат с .NET Core 3.0

GC WorkStationGC
allocate number 1 objet 
heap use 1 mb
GC occurs 0 times
allocate number 2 objet 
heap use 2 mb
GC occurs 0 times
allocate number 3 objet 
heap use 3 mb
GC occurs 0 times
allocate number 4 objet 
heap use 1 mb
GC occurs 1 times
allocate number 5 objet 
heap use 2 mb
GC occurs 1 times
allocate number 6 objet 
heap use 3 mb
GC occurs 1 times
allocate number 7 objet 
heap use 1 mb
GC occurs 2 times
allocate number 8 objet 
heap use 2 mb
GC occurs 2 times
allocate number 9 objet 
heap use 3 mb
GC occurs 2 times
allocate number 10 objet 
heap use 1 mb
GC occurs 3 times
allocate number 11 objet 
heap use 2 mb
GC occurs 3 times
allocate number 12 objet 
heap use 3 mb
GC occurs 3 times
allocate number 13 objet 
heap use 1 mb
GC occurs 4 times
allocate number 14 objet 
heap use 2 mb
GC occurs 4 times
allocate number 15 objet 
heap use 3 mb
GC occurs 4 times
allocate number 16 objet 
heap use 1 mb
GC occurs 5 times
allocate number 17 objet 
heap use 2 mb
....

Программа работает нормально.

...