Почему классам с финализаторами требуется более одного цикла сборки мусора? - PullRequest
4 голосов
/ 27 января 2012

В этой статье написано

Если у объекта есть финализатор, он не сразу удаляется, когда сборщик мусора решает, что он больше не «живой». Вместо этого это становится особый вид root, пока .NET не вызвал метод финализатора. Это означает, что эти объекты обычно требуют более одного мусора коллекция будет удалена из памяти, так как они выживут первыми время, когда они оказываются неиспользованными.

У меня вопрос, почему GC не вызывает finalizer, когда обнаруживает, что на объект больше нельзя ссылаться, и сразу же собирает объект? зачем нужно больше, чем на сборку мусора?

Ответы [ 3 ]

5 голосов
/ 27 января 2012

Два вопроса для рассмотрения:

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

  • Финализатор может воскресить объект, сделав его снова видимым - но обнаружение этого потребует (я подозреваю) еще одного взрыва памяти ... так почему бы просто не подождать до следующего раза, когда это произойдет?

2 голосов
/ 27 января 2012

Потому что (в зависимости от выбранного режима GC), когда он выполняет GC , он должен приостанавливать ключевые части времени выполнения . Следовательно, вы хотите, чтобы это было как можно быстрее. Это создает две проблемы:

  1. он не знает, сколько времени займет запуск финализатора (хотя он имеет жесткое ограничение), и не хочет откладывать возобновление времени выполнения
  2. для надежной работы финализатора должна быть запущена среда выполнения (даже если используется поток GC, код, который вы пишете, возможно, заботится о других потоках)

Для решения обеих проблем те, с ожидающими финализаторами, ставятся в очередь, а затем выполняются после , когда GC завершил (когда работает среда выполнения).

В качестве дополнительного примечания рекомендуется объединять финализаторы с IDisposable и Dispose() отменять финализацию; таким образом, он не нуждается в доработке позже и очищается за один шаг.

0 голосов
/ 03 февраля 2012

Когда запускается сборщик мусора .net, объекты делятся на три категории: объекты, которые достижимы из «нормальной» корневой ссылки, объекты, которые недоступны из любой корневой ссылки, и объекты,недоступны никаким «обычным» корневым ссылкам, но либо запросили получение уведомления, когда они были оставлены, , либо достижимы от других объектов, которые сделали это .Сборщик мусора составляет список объектов в этой третьей категории;этот список хранится как корневая ссылка, что делает все объекты в нем «живыми».Система просматривает элементы в этом списке, но отменяет их запросы на уведомление, запускает метод Finalize () и удаляет их из списка.Если ни одна ссылка на объект не существует нигде после того, как все сказано и сделано, тогда объект будет объявлен «мертвым» в следующем цикле GC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...