Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
40.doc
Скачиваний:
14
Добавлен:
30.04.2022
Размер:
646.66 Кб
Скачать

12.2. Финализация объектов

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

// Класс System.Object

public class Object

{

protected virtual void Finalize(){}

}

За счет его переопределения в специальных классах устанавливается специфическое место для выполнения любой необходимой данному типу логики по очистке. Из-за того, что метод Finalize() по определению является защищенным (protected), вызывать его напрямую из класса экземпляра с помощью операции точки не допускается. Вместо этого метод Finalize () (если он поддерживается) будет автоматически вызываться сборщиком мусора перед удалением соответствующего объекта из памяти.

Вызов метода Finalize() будет происходить либо во время естественной активизации процесса сборки мусора, либо во время его принудительной активизации программным образом с помощью GC. Collect().

При переопределении метода Finalize() в C# нельзя применятьключевое слово override:

class MyResourceWrapper

{

// Ошибка на этапе компиляции

protected override void Finalize () { }

}

Вместо этого для достижения того же эффекта должен применяться синтаксис деструктора (подобно C++). Финализаторы в С# очень похожи на конструкторы тем, что именуются идентично классу, внутри которого определены. Помимо этого, они сопровождаются префиксом в виде тильды (~). В отличие от конструкторов, однако, они никогда не снабжаются модификатором доступа (поскольку всегда являются неявно защищенными), не принимают никаких параметров и не могут быть перегружены (в каждом классе может присутствовать только один финализатор).

Ниже приведен пример написания специального финализатора для класса MyClass, который при вызове заставляет систему выдавать звуковой сигнал.

// Переопределение System.Object.Finalize()

//с использованием синтаксиса финализатора.

class MyClass

{

~MyClass()

{

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

//Обеспечение подачи звукового сигнала при

// уничтожении объекта (только в целях //тестирования).

Console.Beep();

}

}

При размещении объекта в управляемой куче исполняющая среда автоматически определяет, поддерживается ли в нем какой-нибудь специальный метод Finalize(). Если да, тогда она помечает его как финализируемый (finalizable) и сохраняет указатель на него во внутренней очереди, называемой очередью финализации (finalization queue). Эта очередь финализации представляет собой просматриваемую сборщиком мусора таблицу, где перечислены объекты, которые перед удалением из кучи должны быть обязательно финализированы.

Когда сборщик мусора определяет, что наступило время удалить объект из памяти, он проверяет каждую запись в очереди финализации и копирует объект из кучи в еще одну управляемую структуру, называемую таблицей объектов, доступных для финализации (finalization reachable table). После этого он создает отдельный поток для вызова метода Finalize() в отношении каждого из упоминаемых в этой таблице объектов при следующей сборке мусора. В результате получается, что для окончательной финализации объекта требуется как минимум два процесса сборки мусора.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]