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
***** 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
public class Object
{
...
protected virtual void Finalize() {}
}
За счет переопределения метода Finalize()
Finalize() определен как защищенный, вызывать его напрямую из экземпляра класса через операцию точки нельзя. Взамен метод Finalize(), если он поддерживается, будет вызываться На заметку!
Переопределять методFinalize() в типах структур не разрешено. Подобное ограничение вполне логично, поскольку структуры являются типами значений, которые изначально никогда не размещаются в куче и, следовательно, никогда не подвергаются сборке мусора. Тем не менее, при создании структуры, которая содержит неуправляемые ресурсы, нуждающиеся в очистке, можно реализовать интерфейс iDisposable (вскоре он будет описан). Вспомните из главы 4, что структуры ref и структуры ref, допускающие только чтение, не могут реализовывать какой-либо интерфейс, но могут реализовывать метод Dispose().Разумеется, вызов метода Finalize()
GC.Collect(). В предшествующих версиях .NET (но не в .NET Core) финализатор каждого объекта вызывался при окончании работы приложения. В .NET Core нет никаких способов принудительного запуска финализатора даже при завершении приложения.О чем бы ни говорили ваши инстинкты разработчика, подавляющее большинство классов C# не требует написания явной логики очистки или специального финализатора. Причина проста: если в классах используются лишь другие управляемые объекты, то все они в конечном итоге будут подвергнуты сборке мусора. Единственная ситуация, когда может возникнуть потребность спроектировать класс, способный выполнять после себя очистку, предусматривает работу с
В рамках платформы .NET Core неуправляемые ресурсы получаются путем прямого обращения к API-интерфейсу операционной системы с применением служб вызова платформы (Platform Invocation Services — P/Invoke) или в сложных сценариях взаимодействия с СОМ. С учетом сказанного можно сформулировать еще одно правило сборки мусора.