Когда объект регистрируется для завершения, он помещается в очередь завершения. Когда запускается сборщик мусора, все объекты делятся на три категории:
- Те, которые имеют корневую прямую ссылку , отличную от очереди завершения.
- Те, для которых только корневая ссылка *1007* является очередью завершения.
Те, для которых нет корневых ссылок.
Объекты третьего типа просто перестанут существовать, хотя ничего и не заметят. Те из первого типа считаются «живыми». Для объектов среднего типа (включая объекты с финализаторами и другие объекты, на которые финализируемые объекты содержат ссылки ) будут запускаться их финализаторы (если таковые имеются); после того как финализаторы завершены, если финализаторы не хранят корневые ссылки где-либо или не перерегистрируют объекты для завершения, у объектов больше не будет никаких корневых ссылок вообще, и они будут иметь право на следующую сборку мусора.
Единственная реальная опасность использования ссылок на другие объекты во время финализации состоит в том, что, если у объектов нет подходящих блокировок, нет никакого способа узнать, в каком состоянии они могут находиться, когда финализатор пытается их очистить; возможно, они даже могут быть использованы. Вероятно, хорошей идеей является использование Threading.Interlocked.Exchange для проверки и установки флага, указывающего, что выполняется очистка.
Кстати, пара дополнительных моментов, которые Microsoft не подчеркивает в своей документации:
- Поскольку любые объекты, на которые финализируемые объекты содержат прямые или косвенные ссылки, не подходят для сборки мусора, объекты с финализаторами не должны содержать ссылок на любые объекты, не необходимые для финализации.
- Хотя шаблон Microsoft Dispose пытается упростить очистку объектов как управляемыми, так и неуправляемыми ресурсами (я думаю, что лучшими терминами были бы самоочищение и неочищение), такие объекты почти всегда будут удерживать ресурсы для ненужных объектов. во время доработки (не соответствует правилу № 1).
Лучше, IMHO, было бы принять следующий принцип: не самоочищающиеся ресурсы должны быть размещены в их собственных классах, единственная цель которых состоит в том, чтобы управлять их очисткой и выставлять объекты для использования в другом месте; это должны быть единственные классы с финализаторами. Только классы, производные от Object, должны реализовывать финализаторы; другие производные классы, которые добавляют не самоочищающиеся ресурсы, должны инкапсулировать эти ресурсы в отдельные самоочищающиеся классы, а затем хранить ссылки на них.