В C # вызов Dispose удаляет объект из кучи? - PullRequest
5 голосов
/ 03 января 2012

Если я делаю conn.Dispose (); (где conn является экземпляром класса SqlConnection), это очистит объект conn от кучи?

Ответы [ 6 ]

13 голосов
/ 03 января 2012

Нет, вызов Dispose не удаляет соединение из кучи.Когда вы вызываете метод Dispose для экземпляра SqlConnection, все, что вы делаете, - возвращаете соединение с базовым пулом соединений.Это даже не закрывает связь.ADO.NET использует пул соединений.Поэтому, когда вы создаете новый экземпляр SqlConnection, вы не открываете новое соединение, вы просто рисуете соединение из пула соединений, а когда вы вызываете Dispose, вы просто возвращаете это соединение в пул соединений, чтобы его можно было повторно использовать.

Как правило, шаблон IDisposable в .NET предназначен для реализации классами, которые содержат некоторые указатели на некоторые неуправляемые ресурсы.Вызов метода Dispose гарантирует, что эти неуправляемые ресурсы будут правильно освобождены.

Удаление объекта из кучи - это то, что делает сборщик мусора, и когда это происходит, это недетерминированное событие (вы не можете его контролировать).

1 голос
/ 03 января 2012

Из msdn: IDisposable.Dispose

Используйте этот метод для закрытия или освобождения неуправляемых ресурсов, таких как файлы, потоки и дескрипторы, содержащиеся в экземпляре класса, который реализуетэтот интерфейс.

Итак, Dispose о базовых ресурсах, которые находятся вне поля зрения сборщика мусора.Dispose не относится к экземпляру.


будет ли очищать объект conn из кучи?

Экземпляр SqlConnection удалит свой ресурс неуправляемого соединения (возвращаяэто в пул соединений).Экземпляр SqlConnection не «удаляет» себя из памяти - это управляемый объект, и сборщик мусора отвечает за эту работу.

1 голос
/ 03 января 2012

номер

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

Немного не по теме, вы также должны знать, что ключевое слово using работает с IDisposable, например,

using (var disposableObject = new DisposableObject())
{
   ..do stuff with disposableObject..
} //disposableObject.Dispose() implicitly called here.
1 голос
/ 03 января 2012

Нет; это работа сборщика мусора.
Вы вообще не можете явно взаимодействовать с кучей.

Вызов Dispose() закрывает дорогостоящие ресурсы (в данном случае сетевое соединение) детерминистически.

1 голос
/ 03 января 2012

Нет. см msdn Объект все еще живет, пока не исчезнут все ссылки. Небольшой пример:

myObject = new Something();
myObject.Dispose()
myObject.Foo() // still perfectly valid (but pretty ugly)
myObject = null; // now the reference, while still living, could be collected.
GC.Collect(); // now it is quite sure gone. (never call it unless you have good reasons)
0 голосов
/ 04 января 2012

Целью IDisposable является предоставление стандартного средства уведомления объектов о том, что они больше не нужны. Некоторые объекты просят другие объекты (которые могут или не могут даже находиться на одном компьютере!) Делать что-либо от их имени до дальнейшего уведомления. Когда объекту говорят, что он больше не нужен, он может уведомить любые объекты, которые могут действовать от его имени, о том, что они больше не нуждаются в этом.

В качестве простого примера, создание файлового объекта может (косвенно) привести к отправке запроса на файловый сервер, чтобы открыть определенный файл для монопольного доступа. Пока файловый сервер не получит запрос на закрытие файла, он не позволит никому другому в известном юниверсе получить к нему доступ. Пока объект файла необходим, он будет поддерживать монопольный доступ к файлу. Если IDisposable.Dispose вызывается для файлового объекта, он (опять-таки, косвенно) заставляет отправлять «закрытый» запрос на файловый сервер, что позволяет другим программам и компьютерам получить доступ к файлу.

Обратите внимание, что если объект файла просто исчезнет, ​​не уведомив никого о том, что ранее предоставленный исключительный доступ к файлу больше не требуется, сервер может никогда не позволить кому-либо еще использовать файл. Для защиты от проблем такого типа класс файлового объекта может определять обработчик Finalize (). Каждый раз, когда система создает объект класса, который переопределяет Object.Finalize(), система добавляет его в специальный список объектов с «зарегистрированными» обработчиками Finalize. Если такой объект заброшен, сборщик мусора запустит свой метод Finalize, прежде чем он или любые объекты, на которые он имеет прямые или косвенные ссылки, будут фактически удалены из памяти.

Обратите внимание, что целью Dispose является не уничтожение самого файлового объекта, а предоставление ему возможности уведомить объект, предоставляющий монопольный доступ к файлу, о том, что такой доступ больше не нужен. Вызов Dispose для объекта, класс которого переопределяет Object.Finalize(), уведомит сборщик мусора о том, что ему больше не нужно беспокоиться о вызове метода Finalize перед удалением объекта из памяти, но в противном случае он не уничтожит объект.

...