Насколько я понимаю, указатели, содержащиеся в корнях приложения , не установлены в нуль. Это немного нелогично (IMHO), потому что кажется, что самый быстрый способ избавиться от объекта - просто избавиться от указателя на него, так же, как файловая система FAT просто помечает запись FAT для удаления файла. без фактического следования этому «указателю» на байты на диске и установки их в ноль. Я пропустил вопрос на собеседовании, который затронул этот вопрос, поэтому я немного о нем прочитал, несмотря на то, что он практически не применим ко всему, о чем мы беспокоимся ежедневно.
В любом случае ... Джеффри Рихтер написал статью MSDN двенадцать лет назад, посвященную этому. Из его статьи я узнал следующее.
Когда GC запускается, предполагается, что все корни приложения указывают на недоступные объекты. Он бродит по корням, следуя за ними к объектам в куче (или обнаруживая, что они не указывают на что-либо действительное). Он делает это рекурсивно, создавая новый граф достижимых объектов. Затем он перемещается по куче, перемещая действительные объекты вниз и фиксируя их указатели - эффект, который заключается в консолидации свободной памяти в верхней части кучи. В какой-то момент этого процесса граф достижимых объектов копируется обратно в корни приложения, заменяя их. Я не уверен, произойдет ли это до или после сжатия кучи.
Выпуски MSDN Magazine за декабрь 12 и январь 13 также содержат статью об управлении памятью в C #. Я не читал это, но планирую - это могло бы прояснить все это.