如果我做conn.Dispose(); (其中conn是SqlConnection类的一个实例),是否会清除堆中的conn对象?
答案 0 :(得分:13)
不,调用Dispose不会清除堆中的连接。在SqlConnection实例上调用Dispose方法时,只需将连接返回到底层连接池即可。它甚至没有关闭连接。 ADO.NET使用连接池。因此,当您创建SqlConnection的新实例时,您不打开新连接,只需从连接池中绘制一个连接,当您调用Dispose时,只需将此连接返回到连接池,以便可以重用它。
通常,.NET中的IDisposable
模式旨在由包含某些非托管资源的指针的类实现。调用Dispose方法可确保正确释放这些非托管资源。
从堆中删除对象是垃圾收集器所做的事情,当这种情况发生时是一个非确定性事件(你无法控制它)。
答案 1 :(得分:1)
没有。见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)
答案 2 :(得分:1)
没有;那是垃圾收集者的工作 您根本无法与堆显式交互。
调用Dispose()
会确定性地关闭昂贵的资源(在这种情况下,网络连接)。
答案 3 :(得分:1)
没有
IDisposable为对象的“处置”提供了一个众所周知的界面。处置通常是为了显式释放资源,否则这些资源将被保留,直到对象超出范围并被垃圾收集,即从内存中移除对象(堆或堆栈,几乎总是堆)。
稍微偏离主题,您还应该知道using
关键字适用于IDisposable
,例如
using (var disposableObject = new DisposableObject())
{
..do stuff with disposableObject..
} //disposableObject.Dispose() implicitly called here.
答案 4 :(得分:1)
来自msdn:IDisposable.Dispose
使用此方法关闭或释放非托管资源,例如实现此接口的类的实例所持有的文件,流和句柄。
因此,Dispose是关于垃圾收集器视图之外的底层资源。处理与实例无关。
会清除堆中的conn对象吗?
SqlConnection实例将Dispose其非托管连接资源(通过将其返回到连接池)。 SqlConnection实例不会从内存中“释放”自身 - 它是一个托管对象,垃圾收集器负责这项工作。
答案 5 :(得分:0)
IDisposable的目的是提供一种标准方法,通知对象不再需要它们。有些对象要求其他实体(可能在同一台计算机上,也可能不在同一台计算机上!)代表他们做事,直到另行通知为止。当一个对象被告知不再需要它时,它可以通知任何可能代表它的实体他们不再需要这样做。
作为一个简单的例子,创建文件对象可以(间接地)将请求发送到文件服务器以打开特定文件以进行独占访问。在文件服务器收到关闭文件的请求之前,它不允许已知Universe中的任何其他人访问它。只要需要文件对象,它就会保持对文件的独占访问权限。如果在文件对象上调用IDisposable.Dispose,它将(再次,间接)导致将“关闭”请求发送到文件服务器,从而允许其他程序和计算机访问该文件。
请注意,如果文件对象只是消失而没有通知任何人不再需要先前授予的独占文件访问权限,则服务器可能永远不会让其他任何人使用该文件。为了防止此类问题,文件对象的类可以定义Finalize()处理程序。只要系统创建覆盖Object.Finalize()
的类的对象,系统就会将其添加到具有“已注册”Finalize处理程序的特殊对象列表中。如果放弃了这样的对象,垃圾收集器将在它之前运行其Finalize方法,或者它实际上可以从内存中删除任何直接或间接引用的对象。
请注意,Dispose的目的不是销毁文件对象本身,而是允许它通知实体提供对不再需要此类访问的文件的独占访问。对类重写Object.Finalize()
的对象调用Dispose将通知垃圾收集器它不再需要担心在从内存中删除对象之前调用Finalize方法,但不会破坏该对象。