Вопрос о сборщике мусора .NET, когда существуют циклические ссылки - PullRequest
3 голосов
/ 24 января 2009

Мне известно, что сборщик мусора .net обнаруживает циклические ссылки, но мне было интересно, могут ли циклические ссылки сохранять объекты дольше, чем необходимо.

У меня есть циклическая ссылка в моем приложении ASP.NET (предназначенная по причинам, связанным с производительностью), могу ли я обойтись без этого?

Привет

Ответы [ 5 ]

11 голосов
/ 24 января 2009

CLR больше не требуется для удаления циклической ссылки, чем нециклическая ссылка. CLR использует комбинацию методов для сбора мусора. Тем не менее, быстрая версия запускается со всеми корневыми объектами (объектами в стеке или с сильной ручкой GC) Любой объект, который доступен из этих объектов, жив. Все остальное будет собрано. Циклическая ссылка не повлияет на результаты этого алгоритма, кроме того, что CLR должен проверять их, а не ходить кругами

4 голосов
/ 24 января 2009

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

Если существует путь от корня (переменная в стеке или статическая переменная, в основном потому, что они, как известно, являются живыми и не должны быть GC), то этот объект должен живи и не получишь GC'ed.

Если пути нет, то объект мертв и его можно безопасно смонтировать. Циклы просто не имеют значения. Так что нет, циклы не будут влиять на время жизни объектов.

1 голос
/ 08 июля 2010

GC будет собирать любой объект, на который не ссылается корневой объект. Корневыми объектами обычно являются объекты, на которые ссылаются все домены приложений (т.е. загруженные сборки / объекты типа), глобальные и статические ссылки на объекты, все ссылки на объекты в соответствующем стеке каждого потока плюс любые ссылки на объекты, загруженные в данный момент в регистр ЦП.

Во время сбора GC просматривает ссылки на все известные корневые объекты и помечает любой объект, который он находит по пути, как «используемый». Когда все сделано, любые объекты, не отмеченные, могут быть безопасно собраны.

Таким образом, если ни один из ваших объектов не ссылается (прямо или косвенно) на корневой объект, не имеет значения, существуют ли циклические ссылки. Все они будут иметь право на сбор независимо. Я говорю «право», потому что сборщик мусора использует три разные стратегии для сбора подходящих объектов, и по соображениям производительности только одна из них собирает все подходящие объекты при запуске.

Обычно вам не нужно об этом думать, это просто работает. Но есть еще много возможностей для сбора мусора, и вам все равно нужно понимать его основы, чтобы понимать управление памятью и писать код без ошибок, который не пропускает ресурсы и т. Д. Поэтому каждый разработчик .NET должен обратить на это внимание. Вот несколько ресурсов, которые объясняют, как CLR выполняет сборку мусора.

MSDN - Основы работы сборщика мусора и советы по производительности (Rico Mariani)

MSDN Magazine - Сборка мусора (часть 1): Автоматическое управление памятью в Microsoft .NET Framework (Джеффри Рихтер)

MSDN Magazine - Сборка мусора (часть 2): Автоматическое управление памятью в Microsoft .NET Framework (Джеффри Рихтер)

1 голос
/ 25 января 2009

Обычно, если какие-либо статические, локальные переменные, параметры или переменные-члены ссылаются на объект, он недоступен для сборки мусора. Неважно, присутствуют циклические ссылки или нет. Либо на цикл ссылаются, в каких случаях он не собирается, или на него не ссылаются, и в этом случае может быть собран весь цикл.

Если тип реализует финализатор, он будет присваивать коллекцию (и), пока его финализатор не запустится.

0 голосов
/ 24 января 2009

Java GC может обнаруживать циклы и обрабатывать их. Могу поспорить, что C # GC тоже может.

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