Методы "Finalize" и деструкторы
Обновлен: Ноябрь 2007
Для большинства объектов, создаваемых приложением, сборщик мусора обязательно автоматически выполнит необходимые задачи по управлению памятью. Однако при создании объектов, которые инкапсулируют неуправляемые ресурсы, по завершении использования неуправляемых ресурсов в приложении приходится освобождать их явно. Основным типом неуправляемых ресурсов являются объекты, образующие обертку для таких ресурсов операционной системы, как файл, окно или сетевое подключение. Хотя сборщик мусора может отслеживать время жизни объекта, инкапсулирующего неуправляемые ресурсы, он не имеет определенных сведений о том, как освобождать эти ресурсы. Для этих типов объектов в .NET Framework имеется метод Object.Finalize, который позволяет объекту должным образом очищать свои неуправляемые ресурсы, когда сборщик мусора возвращает используемую объектом память. По умолчанию метод Finalize ничего не делает. Если же требуется, чтобы сборщик мусора до освобождения памяти объекта выполнил завершающие операции, следует переопределить метод Finalize в используемом классе.
Примечание. |
---|
Для реализации метода Finalize в C# необходимо использовать синтаксис деструктора. В .NET Framework версии 2.0 язык Visual C++ предоставляет свой собственный синтаксис для реализации метода Finalize, как описано в разделе Destructors and Finalizers in Visual C++. В .NET Framework версии 1.0 и 1.1 язык Visual C++ использовал синтаксис деструктора для метода Finalize, как это делается в C#. |
Сборщик мусора следит за объектами, имеющими методы Finalize с помощью внутренней структуры, которая называется очередью завершения. При каждом создании в приложении объекта, имеющего метод Finalize, сборщик мусора заносит в очередь завершения новое вхождение, которое указывает на этот объект. Очередь завершения содержит вхождения для всех объектов, находящихся в управляемой куче, для которых, прежде чем сборщик мусора сможет освободить их память, должен быть вызван их код завершения.
Примечание. |
---|
В примере кода, предоставляемом для метода GC.KeepAlive, показывается, как активная операция сборки мусора может вызвать запуск метода завершения, в то время как член восстанавливаемого объекта по-прежнему выполняется, и как использовать метод KeepAlive для предотвращения этого. |
Метод Finalize не должен выдавать исключения, поскольку они не могут обрабатываться приложением и могут привести к завершению работы приложения.
Реализация методов Finalize или деструкторов может отрицательно воздействовать на производительность, и злоупотреблять ими не рекомендуется. Для освобождения памяти, используемой объектами, посредством методов Finalize требуется, по крайней мере, две операции сборки мусора. Когда сборщик мусора выполняет сборку, он освобождает память недоступных объектов без использования методов завершения. На этом этапе он не может собрать недоступные объекты, которые имеют такие методы завершения. Вместо этого, он удаляет вхождения этих объектов из очереди завершения и помещает их в список объектов, отмеченных как готовые для завершения. Вхождения в этом списке указывают на объекты в управляемой куче, которые готовы к вызову их кода завершения. Сборщик мусора вызывает методы Finalize для объектов из этого списка и затем удаляет вхождения из списка. Следующая сборка мусора определит, что завершенные объекты на самом деле являются мусором, так как они больше не адресуются вхождениями в списке объектов, отмеченных как готовые для завершения. В этой будущей сборке мусора и происходит фактическое освобождение памяти объектов.
См. также
Основные понятия
Переопределение метода Finalize
Синтаксис деструкторов в C# и C++