Литмир - Электронная Библиотека
A
A

...

// Исследовать только объекты поколения 0.

GC.Collect(0);

GC.WaitForPendingFinalizers();

...

Кроме того, методу

Collect()
можно передать во втором параметре значение перечисления
GCCollectionMode
для точной настройки способа, которым исполняющая среда должна принудительно инициировать сборку мусора. Ниже показаны значения, определенные этим перечислением:

public enum GCCollectionMode

{

  Default,  // Текущим стандартным значением является Forced.

  Forced,   // Указывает исполняющей среде начать сборку мусора немедленно

  Optimized // Позволяет исполняющей среде выяснить, оптимален

            // ли текущий момент для удаления объектов.

}

Как и при любой сборке мусора, в результате вызова

GC.Collect()
уцелевшие объекты переводятся в более высокие поколения. Модифицируйте операторы верхнего уровня следующим образом:

Console.WriteLine("***** Fun with System.GC *****");

// Вывести оценочное количество байтов, выделенных в куче.

Console.WriteLine("Estimated bytes on heap: {0}",

  GC.GetTotalMemory(false));

// Значения MaxGeneration начинаются c 0.

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("\nGeneration of refToMyCar is: {0}",

  GC.GetGeneration(refToMyCar));

// Создать большое количество объектов для целей тестирования.

object[] tonsOfObjects = new object[50000];

for (int i = 0; i < 50000; i++)

{

  tonsOfObjects[i] = new object();

}

// Выполнить сборку мусора только для объектов поколения 0.

Console.WriteLine("Force Garbage Collection");

GC.Collect(0, GCCollectionMode.Forced);

GC.WaitForPendingFinalizers();

// Вывести поколение refToMyCar.

Console.WriteLine("Generation of refToMyCar is: {0}",

  GC.GetGeneration(refToMyCar));

// Посмотреть, существует ли еще tonsOfObjects[9000].

if (tonsOfObjects[9000] != null)

{

   Console.WriteLine("Generation of tonsOfObjects[9000] is: {0}",

                      GC.GetGeneration(tonsOfObjects[9000]));

}

else

{

  Console.WriteLine("tonsOfObjects[9000] is no longer alive.");

                  // tonsOfObjects[9000] больше не существует

}

// Вывести количество проведенных сборок мусора для разных поколений.

Console.WriteLine("\nGen 0 has been swept {0} times",

  GC.CollectionCount(0));  // Количество сборок для поколения 0

Console.WriteLine("Gen 1 has been swept {0} times",

  GC.CollectionCount(1));  // Количество сборок для поколения 1

Console.WriteLine("Gen 2 has been swept {0} times",

  GC.CollectionCount(2));  // Количество сборок для поколения 2

Console.ReadLine();

Здесь в целях тестирования преднамеренно был создан большой массив типа

object
(состоящий из 50000 элементов). Ниже показан вывод программы:

***** 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

Forcing Garbage Collection

Generation of refToMyCar is: 1

Generation of tonsOfObjects[9000] is: 1

Gen 0 has been swept 1 times

Gen 1 has been swept 0 times

Gen 2 has been swept 0 times

К настоящему моменту вы должны лучше понимать детали жизненного цикла объектов. В следующем разделе мы продолжим изучение процесса сборки мусора, обратившись к теме создания финализируемых объектов и освобождаемых объектов. Имейте в виду, что описываемые далее приемы обычно необходимы только при построении классов С#, которые поддерживают внутренние неуправляемые ресурсы.

Построение финализируемых объектов

В главе 6 вы узнали, что в самом главном базовом классе .NET Core,

System.Object
, определен виртуальный метод по имени
Finalize()
. В своей стандартной реализации он ничего не делает:

// System.Object

187
{"b":"847442","o":1}