В качестве связанного замечания: механизм сборки мусора в .NET 4.0 и последующих версиях был усовершенствован с целью дальнейшего сокращения времени приостановки заданного потока, которая связана со сборкой мусора. Конечным результатом таких изменений стало то, что процесс очистки неиспользуемых объектов поколения 0 или поколения 1 был оптимизирован и позволяет обеспечить более высокую производительность приложений (что действительно важно для систем реального времени, которые требуют небольших и предсказуемых перерывов на сборку мусора).
Тем не менее, важно понимать, что ввод новой модели сборки мусора совершенно не повлиял на способ построения приложений .NET Core. С практической точки зрения вы можете просто разрешить сборщику мусора выполнять свою работу без непосредственного вмешательства с вашей стороны (и радоваться тому, что разработчики в Microsoft продолжают улучшать процесс сборки мусора в прозрачной манере).
Тип System.GC
В сборке mscorlib.dll предоставляется класс по имени System.GC, который позволяет программно взаимодействовать со сборщиком мусора, применяя набор статических членов. Имейте в виду, что необходимость в прямом взаимодействии с классом System.GC внутри разрабатываемого кода возникает редко (если вообще возникает). Обычно единственной ситуацией, когда будут использоваться члены System.GC, является создание классов, которые внутренне работают с System.GC (полные сведения можно найти в документации по .NET Core).
Чтобы проиллюстрировать использование типа System.GC для получения разнообразных деталей, связанных со сборкой мусора, обновите операторы верхнего уровня в проекте SimpleGC:
using System;
Console.WriteLine("***** Fun with System.GC *****");
// Вывести оценочное количество байтов, выделенных в куче.
Console.WriteLine("Estimated bytes on heap: {0}",
GC.GetTotalMemory(false));
// Значения MaxGeneration начинаются c 0, поэтому при выводе добавить 1.
Console.WriteLine("This OS has {0} object generations.\n",
(GC.MaxGeneration + 1));
Car refToMyCar = new Car("Zippy", 100);
Console.WriteLine(refToMyCar.ToString());
// Вывести поколение объекта refToMyCar.
Console.WriteLine("Generation of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
Console.ReadLine();
Вы должны получить примерно такой вывод:
***** Fun with System.GC *****
Estimated bytes on heap: 75760
This OS has 3 object generations.
Zippy is going 100 MPH
Generation of refToMyCar is: 0
Методы из табл. 9.2 более подробно обсуждаются в следующем разделе.
Принудительный запуск сборщика мусора
Не забывайте о том, что основное предназначение сборщика мусора связано с управлением памятью вместо программистов. Однако в ряде редких обстоятельств сборщик мусора полезно запускать принудительно, используя метод GC.Collect(). Взаимодействие с процессом сборки мусора требуется в двух ситуациях:
• приложение входит в блок кода, который не должен быть прерван вероятной сборкой мусора;
• приложение только что закончило размещение исключительно большого количества объектов, и вы хотите насколько возможно скоро освободить крупный объем выделенной памяти.
Если вы посчитаете, что принудительная проверка сборщиком мусора наличия недостижимых объектов может принести пользу, тогда можете явно инициировать процесс сборки мусора:
...
// Принудительно запустить сборку мусора
// и ожидать финализации каждого объекта.
GC.Collect();
GC.WaitForPendingFinalizers();
...