Подтвердить что ты не робот

Реализация WeakReference в .NET.

Я понимаю и ценю полезность класса System.WeakReference в .NET Framework, но мне интересно узнать подробности реализации.

Как реализована функция WeakReference в .NET? MSDN подробно обсуждает использование WeakReference, но имеет небольшие детали, которые я видел о том, как это работает под капотом.

Как CLR отслеживает ссылку и знает, чтобы исключить внутренний дескриптор при сборке Цели, не предотвращая GC? Требуется ли специальная обработка в самой CLR?

Моя основная проблема заключалась в том, будут ли последствия использования WeakReferences влиять на производительность (особенно если вы используете многие из них), которые отличаются от результатов использования стандартных ссылок на объекты.

4b9b3361

Ответ 1

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

Это означает, что GC хранит список всех слабых ссылок, которые он должен обновлять при сборе объектов. Это также означает, что при использовании слабой ссылки есть некоторые накладные расходы.

Таким образом, каждая слабая ссылка означает немного больше работы для сборщика мусора, но, с другой стороны, также делает каждую регулярную ссылку, даже если она меньше. Конечно, вы должны быть осторожны в использовании множества слабых ссылок, но если вам нужно, чтобы управление памятью хорошо работало с вашими объектами, это должно привести к уменьшению небольших накладных расходов, которые он вызывает.

Ответ 2

Вы упомянули MSDN; вы уже видели эту статью?

http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Также ознакомьтесь с главой 19 в "Прикладной Программе Microsoft.NET Framework" того же автора (Джеффри Рихтер). Глава посвящена сборке мусора и содержит раздел о внутренних компонентах WeakReference.

В общем случае, если вы получаете доступ к большому количеству Targets внутри WeakReferences, то это происходит просто потому, что WeakRef выполняет некоторую работу (главным образом для обеспечения безопасности потоков) перед возвратом цели. Это, очевидно, не так дешево, как использование ссылки на объект напрямую. С другой стороны, вы получаете некоторую производительность при хранении ссылок на большие объекты, поскольку сборщик мусора имеет больше возможностей при возникновении соображений памяти.

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