Понимание gcroot

Я читал эту статью чтобы понять шаблон gcroot. Я понимаю

gcroot предоставляет ручки в мусор, собранный кучей

и что

сами ручки не мусор собраны.

Я не понимаю, что следующее:

Когда объект CLR перемещается с мусорная сборка, ручка вернет новый адрес объект. Переменная не обязательно должна быть закреплена до того, как она будет назначена gcroot.

Означает ли это, что объект CLR будет удален сборщиком мусора, даже если есть дескриптор gcroot, ссылающийся на этот объект?

Что такое "новый адрес", на который он ссылается? И что это значит, что "переменная не должна быть закреплена до того, как она будет назначена шаблону gcroot"?

Ответ 1

Сбор мусора не просто удаляет объекты без ссылок, он также перемещается вокруг объектов, на которые все еще ссылаются, например. для дефрагментации пула свободной памяти. Когда в статье рассказывается об объектах, перемещающихся в куче CLR, возможно, что "когда сбор мусора перемещает объект с неподвижными ссылками, дескриптор gcroot будет автоматически обновлен, чтобы все еще указывать на объект CLR".

Вы можете помешать GC перемещать объекты вокруг, используя ключевое слово pin_ptr, например:

Object ^obj = gcnew <something>;
pin_ptr pinned = obj;  /* obj won't move due to GC as long as pinned is in scope. */
/* do something interop-y here, pass to native code in a DLL, etc. */

Подробнее о фиксации см. в этой статье.

Наблюдение. В статье может быть опечатка. Если бы он сказал "внутри кучи, собранной мусором" вместо "с кучей мусора", это улучшило бы ваше понимание? Способ, который он сформулировал в статье, звучит так, будто сама земля будет двигаться под вашими ногами всякий раз, когда GC очищает дом.