С#: В каких случаях вы должны исключать ссылки?

Профилировщик CLR также может выявить, какие методы распределяют больше хранилища, чем вы ожидали, и можете выявить случаи, когда вы непреднамеренно сохраняете ссылки на бесполезные графические объекты, которые в противном случае могли бы быть восстановлены GC. (Обычным шаблоном проектирования проблем является кеш-память программного обеспечения или таблица поиска элементов, которые больше не нужны или безопасны для последующего восстановления. Трагично, когда кеш хранит графические объекты в течение их полезного срока службы. Вместо этого обязательно null ссылки на объекты, которые вам больше не нужны.) - Написание более быстрого управляемого кода

Я не думаю, что я действительно когда-либо отказывался от ссылки раньше. Я предполагаю, что вам не всегда нужно это делать, но я думаю, что также есть моменты, когда важно помнить об этом. Но что это такое? Когда вы должны отклонять ссылки?

Ответ 1

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

Для локальных переменных это почти никогда не требуется, поскольку GC может обнаружить последнюю возможную точку в коде, где будет доступна переменная. Однако если вы используете переменную, объявленную за пределами цикла во время первой итерации, но вы знаете, что вам не понадобится ее для последующих итераций, вы можете установить ее значение null, чтобы помочь объекту получить право на GC ранее.

По моему опыту, очень редко можно найти себя в этой ситуации. Я почти никогда не собирал заданные переменные в нуль для GC. Обычно все переменные-члены внутри объекта являются "полезными", пока сам объект не станет подходящим для GC. Если вы обнаружите переменные-члены, которые не полезны для всего жизненного цикла объекта, вы можете увидеть, указывает ли это на проблему с дизайном.

Ответ 2

Важно, если у вас давно сохранились объекты (например, пример кеша в вашей цитате), содержащие ссылки на короткоживущие объекты (например, элементы кэша). Другими примерами долгоживущих объектов могут быть одиночные объекты, экземпляр основной формы в приложении Windows Forms, экземпляр приложения приложения ASP.NET и т.д.

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

Ответ 3

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

Если у вас есть Эффективная Java, посмотрите на пункт 5, есть пример реализации стека с утечками памяти, потому что объекты ссылки не исключены. Если у вас нет этой книги, вы можете посмотреть эту часть в Google Books здесь.