Сборка мусора: необходимо ли устанавливать большие объекты в null в методе Dispose? - PullRequest
7 голосов
/ 08 сентября 2008

Нужно ли устанавливать большие объекты на null при реализации метода Dispose()?

Ответы [ 6 ]

5 голосов
/ 08 сентября 2008

Не обычно.

Сборщик мусора ищет корневые объекты, а циклические зависимости не предотвращают сбор, если ни один объект не является корневым.

Существует предостережение: если объект A имеет ссылку на объект B, а объект B удаляется, вы можете захотеть очистить это отношение, иначе вы можете получить утечку. Наиболее распространенное место этой поверхности - обработчики событий (ссылка из A-> B - это та, что B контролирует, потому что она подписана на событие в A). В этом случае, если A все еще укоренен, B невозможно собрать, даже если он был удален.

5 голосов
/ 08 сентября 2008

Если у класса есть метод Dispose, лучше всего вызывать его. причина за этим стоит то, что Dispose запускается при вызове, тогда как установка объекта null просто добавляет запись в очередь Finalize в GC, и мы не можем определить, когда GC будет работать.

Нет преимущества в производительности при реализации метода Dispose для типов, которые используют только управляемые ресурсы (например, массивы), поскольку они автоматически возвращаются сборщиком мусора. Используйте метод Dispose в первую очередь для управляемых объектов, которые используют собственные ресурсы, и для объектов COM, которые доступны для .NET Framework. Управляемые объекты, использующие собственные ресурсы (например, класс FileStream), реализуют интерфейс IDisposable.

Изящное средство ввода в действие Dispose использует конструкцию «using». Для тех из вас, кто может быть не знаком с этой конструкцией, она предоставляет средство для простоты вызова Dispose () для экземпляра, который реализует IDisposable, даже если во время операции создается исключение. Ниже приведен пример использования конструкции:

using(DisposableClass dc = new DisposableClass()) 
{ 
   dc.PerformActionOnUmanagedResources(); 
   dc.PerformAnotherActionOnUmanagedResources(); 
} 

В предыдущем примере, если исключение было сгенерировано в методе PerformActionOnUmanagedResources (), хотя метод PerformAnotherActionOnUmanagedResources () не будет обработан, блок using будет по-прежнему неявно вызывать метод Dispose для dc, обеспечивая освобождение любых неуправляемых ресурсов .

3 голосов
/ 08 сентября 2008

Цель метода dispose - освободить все ресурсы, связанные с вашим классом и классом родителя, вызвав метод dispose базового класса. Прочитайте эту ссылку, она должна немного прояснить ситуацию:

http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

1 голос
/ 08 сентября 2008

Это не обязательно, как отмечали другие, но это хорошая практика и помогает при отладке.

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

Та же логика применяется для установки нулевых указателей на элементы в деструкторах C ++ после их удаления. Нет необходимости для этого, но это поможет с устранением неисправностей позже.

1 голос
/ 08 сентября 2008

что вы подразумеваете под "крупным объектом"?

Вы должны хотя бы вызвать Dispose () для любого члена, реализующего IDisposable.

0 голосов
/ 27 мая 2009

Подумайте немного о назначении одноразовых методов: обычно это потому, что вы держите какой-то ресурс, который не будет освобожден во время сборки мусора. Обычно это что-то вроде подключения к базе данных или дескриптор файла. Таким образом, после вызова метода Dispose все эти ресурсы были освобождены.

Я бы сказал, что нули, плавающие вокруг, более вредны, чем "зомби" объекты, плавающие вокруг.

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