Вывоз мусора:Необходимо ли присваивать большим объектам значение null в методе Dispose?

StackOverflow https://stackoverflow.com/questions/49950

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Обычно нет.

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

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

Другие советы

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

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

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

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

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

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

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

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

Однако вам следует, по крайней мере, вызвать Dispose() для любого элемента, реализующего IDisposable .

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top