.net CLR связанный вопрос - PullRequest
       5

.net CLR связанный вопрос

1 голос
/ 01 ноября 2009

Это вопрос, связанный с .net CLR.

У меня есть 3 объекта, объект A, B, C

A обозначает B и B обозначает c

Что произойдет с этими объектами в куче, если я убью Объект «А» явно. Что будет собирать мусор? (Объект А или В или С или все?)

Может ли кто-нибудь подробно объяснить процесс сбора мусора в этом сценарии.

Заранее спасибо SNA

Ответы [ 3 ]

9 голосов
/ 01 ноября 2009

Во-первых - вы не можете "убить Объект" A "явно"; Вы можете очистить ссылку на него, но это просто устанавливает локальную переменную на null и не имеет ничего общего с реальным объектом в управляемой куче. Вы можете Dispose() это, но это ничего не имеет отношения к GC.

Все зависит; может что-нибудь еще см. B / C? Если нет, то они имеют право на сбор. Но GC недетерминирован; это происходит только тогда, когда он выбирает. В какое-то неопределенное время GC включается, обнаруживает, что эти объекты недоступны, и удаляет их. В процессе он проверит наличие финализаторов (которые еще не выполнены) и выполнит финализаторы (в 2 этапа).

Одна вещь, о которой люди часто забывают в терминах достижимости, это события; если B / C подписаться на события долгоживущего объекта, тогда B / C достижимы (издателем событий).


уточнить; GC создает дерево из корневых объектов (потоков и т. Д.). Идет каждая ссылка , отмечая все объекты, которые могут быть достигнуты. Все, что не помечено в конце, может быть собрано. Это позволяет избежать проблем с COM / COM +, связанных с утечками памяти из-за разрозненных островков данных, где X => Y и Y => X (поэтому и X, и Y имеют положительный реф-счет, поэтому ни один из них не очищается).

1 голос
/ 01 ноября 2009

В .NET нет способа фактически убить / удалить объект. Все, что вы можете сделать явно, это избавиться от объекта. Это не более, чем простой вызов Dispose () для вашего объекта. Это позволит вам очистить ваш объект до того, как он может быть собран сборщиком мусора в более позднее время (что вы не можете реально навредить). См. IDisposable для более подробной информации. Второй вариант, чтобы получить возможность очистить ваш объект до того, как он будет собран GC, - реализовать финализатор . В отличие от Dispose () он будет вызываться GC автоматически. Опять же, оба способа - это просто способ очистить любые ресурсы, прежде чем объект перестанет существовать.

Таким образом, чтобы ответить на ваш вопрос, если ваш объект A «убит», что происходит только тогда, когда на него больше не ссылается ни один другой объект, B и C «убивают», ЕСЛИ на них ссылаются только через A. Обычно вы этого не делаете. иметь какое-либо влияние на то, когда это на самом деле происходит. Все, что вы можете сделать, это внедрить финализатор, чтобы получать уведомления, когда это произойдет. GC - это фоновая служба, которая работает в отдельном потоке, который следует сложной логике, когда фактически удаляет объекты.

Если вы хотите получить общее представление о том, как работает GC, я бы предложил следующие две статьи . Несмотря на то, что они немного устарели, они по-прежнему полностью применимы.

1 голос
/ 01 ноября 2009

Первое недоразумение может заключаться в том, что вы не можете явно уничтожить управляемый объект.

Вы можете освободить неуправляемую память, которую вы выделили самостоятельно, но которая не управляется и в любом случае не подлежит сборке мусора.

Если для ссылки задано значение A, равное нулю, или если она выходит за пределы области видимости, ссылки на B & C не будут появляться, и следующая коллекция GC позаботится об этом.

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