Все ли финализаторы вызываются во время сборки мусора? - PullRequest
4 голосов
/ 22 декабря 2009

Допустим, я пытаюсь выделить 100 байтов, но, поскольку в моей куче GC нет 100 байтов, запускается сборка мусора. Кроме того, в моей куче GC есть 100 МБ недоступных объектов. Насколько я понимаю, когда GC освободил 100 байтов, он мог решить остановить сбор и продолжить выполнение программы. Допустим, GC не освободил объекты стоимостью 50 МБ, которые равны 100 различным объектам.

У меня такой вопрос: GC вызывает все финализаторов? даже если он не собирается их удалять? (в этом случае 100 недоступных объектов, которые GC решил не удалять).

Ответы [ 5 ]

14 голосов
/ 22 декабря 2009

Проблема заключается в том, что все, что здесь может быть деталью реализации, может отличаться для x86 / x64 / ia64, сервера против рабочей станции (очень разный профиль GC), Mono против MS .NET, версии ОС, .NET / CLI основная версия, версия исправления .NET / CLI, Compact Framework, Micro Framework и т. д.

Я не думаю, что вы должны принимать любое определенное поведение, кроме "объекты с финализаторами, которые не используются, вероятно, будут завершены в какой-то момент, но даже это не гарантировано".

1 голос
/ 19 февраля 2011

Сборка мусора в .net имеет два аспекта: финализация и уничтожение. Когда объект, имеющий финализатор, создан, он добавляется в специальный список, который я назову «финализируемым» списком. Каждый раз, когда запускается сборщик мусора, он идентифицирует объекты, которые ничем не достижимы, те, которые доступны только из списка «финализируемых» или объектов в нем, и те, которые доступны чем-то другим, не проходя через список «финализируемых». Объекты, которые вообще недоступны, уничтожаются. Те, которые доступны только из «финализируемого» списка или объектов в нем, удаляются из этого списка и помещаются в список «финализировать сейчас». Объекты, которые достижимы чем-то кроме «финализируемого» списка, выживают в GC. Пока GC сортирует объекты по этим трем категориям, выполнение всего кода останавливается. После завершения GC выполнение кода возобновляется, и специальный поток запускает метод Finalize всех объектов в списке «Завершить сейчас».

Обратите внимание, что объекты в списке "завершить сейчас", а также любые объекты, на которые они ссылаются, не будут собираться мусором, пока они находятся в этом списке; они могут получить право на сборку мусора только после запуска финализатора. Как только они перестают быть в списке «завершить сейчас», они могут снова получить право на сбор.

1 голос
/ 22 декабря 2009

«как только GC освободит 100 байтов, он может решить остановить сбор» - нет, GC не остановит сбор. Он всегда будет собирать поколение 0. Если этого недостаточно, продолжайте с Gen1 и Gen2 + LOB.

0 голосов
/ 22 декабря 2009

GC делает несколько проходов. Он ищет недоступные объекты и, когда находит их, проверяет, есть ли у них финализатор. Если есть финализатор, он помещает их в отдельную очередь финализаторов и, если нет, очищает их. Таким образом, при первом проходе он на самом деле не вызывает никаких финализаторов, он просто организует объекты в зависимости от того, есть ли у них финализаторы.

0 голосов
/ 22 декабря 2009

Ответ - нет. Единственный раз, когда запускаются финализаторы, это когда объект уничтожается.

...