Ответ 1
Таким образом, он может работать в другом потоке и, таким образом, не блокировать основной поток GC.
Вы можете много узнать о GC из этой статьи MSDN.
Как я понимаю, сборщик мусора в С# поместит все объекты класса в очередь финализации, как только я реализую деструктор класса. Когда я читал документацию для GC.Suppresfinalize, он упоминает, что заголовок объекта уже имеет бит для завершения завершения вызова.
Мне интересно, почему разработчикам GC пришлось поставить все объекты в очередь и задержать освобождение памяти на 1-2 цикла. Не могли ли они просто взглянуть на флаг бита при освобождении памяти, затем вызвать финализацию объекта и затем освободить память?
Без сомнения, я идиот, и я не могу понять работу GC. Я задаю этот вопрос только для того, чтобы улучшить свое понимание или заполнить недостающий пробел в моих знаниях.
EDIT: если флаг бит для suppressfinalize, разработчики GC могли бы добавить в этот заголовок объект еще один флаг, no?
Таким образом, он может работать в другом потоке и, таким образом, не блокировать основной поток GC.
Вы можете много узнать о GC из этой статьи MSDN.
Здесь есть большое объяснение.
Что такое конечная точка Finalizer и Control + ThreadMethodEntry?
По сути, аргументация состоит в том, что не всегда может быть идеальным для GC, чтобы ждать завершения кода финализатора, поэтому финализаторы очередей позволяют завершить отсрочку до тех пор, пока это станет более удобным.
Желательно, чтобы паузы для мусора были как можно короче. С этой целью запуск финализаторов обычно откладывается на более поздний срок, когда выполняется безумная работа сборки мусора. Вместо этого он выполняется в фоновом режиме в отдельном потоке.
Сборщик мусора не идентифицирует и не проверяет мусор, кроме, возможно, при обработке кучи больших объектов. Вместо этого его поведение похоже на поведение пинсеттера для боулинга, снимающего мертвое поле между бросками: пинсеттер захватывает все штифты, которые все еще стоят, поднимает их с поверхности полосы и затем беспроблемно пробегает полосу подметания через переулок за сколько контактов на этой поверхности. Сметание оптовой памяти намного быстрее, чем определение отдельных объектов, которые нужно удалить. Если 1% объектов имеют финализаторы (реальное число, вероятно, даже меньше), тогда необходимо будет изучить 100 заголовков объектов, чтобы найти каждый объект, подлежащий окончательному окончанию. Наличие отдельного списка объектов, которые имеют финализаторы, делает ненужным для GC даже смотреть на любые объекты мусора, которые этого не делают.
@Jason: это верно для f-достижимой очереди. Но IMHO не объясняет, почему существует окончательная версия.
Я предполагаю, что финализация-очереди должна добавить другую информацию, которая поможет GC провести различие между всеми возможными состояниями жизни объекта, цикл.
Флаг завершения в заголовке объекта говорит: "объект должен быть финализирован" или "объект не должен быть финализирован", но он не говорит, что финализация уже произошла.
Но, честно говоря, я не понимаю, зачем это нужно в текущей реализации процесса завершения.
В самом деле, вот наивный рабочий процесс, который я себе представляю без очереди финализации:
Похоже, что в этих сценариях нет необходимости в очереди финализации, полезен только флаг финализации.
Одна из возможных причин может заключаться в том, что с концептуальной точки зрения может существовать правило вроде: "объект собирается тогда и только тогда, когда он не ссылается ни на один корень". Поэтому, не имея очереди финализации, и основываясь на решении собирать объект в самом состоянии объекта, проверяя флаг завершения, несовместимо с этим правилом.
Но на самом деле я не думаю, что реализация GC основана на догматическом применении таких теоретических правил, но только на прагматическом выборе; поэтому очевидно, что мне не хватает некоторых ключевых сценариев, где GC нуждается в очереди финализации, чтобы знать, что делать при сборе объекта, но какие?