在C#中,调用Dispose会从堆中删除对象吗?
如果我执行 conn.Dispose(); (其中 conn 是 SqlConnection 类的实例),这会从堆中清除 conn 对象吗?
If I do a conn.Dispose(); (where conn is an instance of a SqlConnection Class), will that clear the conn object from the heap?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不,调用 Dispose 不会清除堆中的连接。当您在 SqlConnection 实例上调用 Dispose 方法时,您所做的就是将连接返回到底层连接池。它甚至不关闭连接。 ADO.NET 使用连接池。因此,当您创建 SqlConnection 的新实例时,您不需要打开新连接,您只需从连接池中提取一个连接,并且当您调用 Dispose 时,您只需将此连接返回到连接池,以便可以重用它。
一般来说,.NET 中的 IDisposable 模式旨在由保存一些指向某些非托管资源的指针的类来实现。调用 Dispose 方法可确保那些非托管资源得到正确释放。
从堆中删除对象是垃圾收集器所做的事情,当发生这种情况时,这是一个非确定性事件(您无法控制它)。
No, calling Dispose doesn't clear the connection from the heap. When you call the Dispose method on a SqlConnection instance all you do is return the connection to the underlying connection pool. It doesn't even close the connection. ADO.NET uses a connection pool. So when you create a new instance of SqlConnection you do not open a new connection, you simply draw a connection from the connection pool and when you call Dispose you simply return this connection to the connection pool so that it can be reused.
In general the
IDisposable
pattern in .NET is intended to be implemented by classes that hold some pointers to some unmanaged resources. Calling the Dispose method ensures that those unmanaged resources will be properly released.Deleting an object from the heap is what the Garbage Collector does and when this happens is a non-deterministic event (you have no control over it).
否。请参阅 msdn
该对象仍然存在,直到所有引用都消失。
一个小例子:
No. see msdn
The object still lives, until all references are gone.
A small example:
不;这是垃圾收集器的工作。
您根本无法显式地与堆交互。
调用 Dispose() 会确定性地关闭昂贵的资源(在本例中为网络连接)。
No; that's the garbage collector's job.
You cannot explicitly interact with the heap at all.
Calling
Dispose()
closes expensive resources (in this case, a network connection) deterministically.不
。IDisposable 提供了一个众所周知的用于“处置”对象的接口。处置通常是为了显式释放资源,否则这些资源将被保留,直到对象超出范围并被垃圾收集,即从内存(堆或堆栈,几乎总是堆)中删除对象时。
稍微偏离主题,您还应该知道
using
关键字与IDisposable
配合使用,例如No.
IDisposable provides a well known interface for the 'disposal' of objects. Disposal is generally for the purpose of explicitly releasing resources that would otherwise be held until the object fell out of scope and was garbage collected, which is when an object is removed from memory (heap or stack, almost always heap).
Slightly off topic, you should also be aware that the
using
keyword works withIDisposable
e.g.来自msdn: IDisposable.Dispose
因此,Dispose 涉及垃圾收集器视野之外的底层资源。 Dispose 与实例无关。
SqlConnection 实例将释放其非托管连接资源(通过将其返回到连接池)。 SqlConnection 实例不会从内存中“处置”自身 - 它是一个托管对象,垃圾收集器负责这项工作。
From msdn: IDisposable.Dispose
So, Dispose is about underlying resources that are outside the view of the garbage collector. Dispose is not about the instance.
The SqlConnection instance will Dispose its unmanaged connection resource (by returning it to the connection pool). The SqlConnection instance does not "Dispose" itself from memory - it's a managed object and the Garbage Collector is responsible for that work.
IDisposable 的目的是提供一种标准方法来通知对象不再需要它们。某些对象要求其他实体(可能位于或什至不在同一台计算机上!)代表它们执行操作,直至另行通知。当一个对象被告知不再需要它时,它可以通知任何可能代表其行事的实体它们不再需要这样做。
作为一个简单的示例,创建文件对象可能(间接)导致向文件服务器发送请求以打开特定文件以进行独占访问。在文件服务器收到关闭文件的请求之前,它不会允许已知宇宙中的任何其他人访问它。只要需要该文件对象,它就会保持对该文件的独占访问。如果在文件对象上调用 IDisposable.Dispose,它将(再次间接)导致向文件服务器发送“关闭”请求,从而允许其他程序和计算机访问该文件。
请注意,如果文件对象只是消失而不通知任何人不再需要先前授予的独占文件访问权限,则服务器可能永远不会让其他任何人使用该文件。为了防止出现此类问题,文件对象的类可以定义 Finalize() 处理程序。每当系统创建一个重写
Object.Finalize()
的类的对象时,系统都会将其添加到具有“已注册”Finalize 处理程序的特殊对象列表中。如果此类对象被废弃,垃圾收集器将在该对象或其直接或间接引用的任何对象实际从内存中删除之前运行其 Finalize 方法。请注意,Dispose 的目的不是销毁文件对象本身,而是允许它通知正在提供文件独占访问权限的实体不再需要此类访问权限。对类重写
Object.Finalize()
的对象调用 Dispose 将通知垃圾收集器,它不再需要担心在从内存中删除该对象之前调用 Finalize 方法,但否则不会销毁该物体。The purpose of IDisposable is to provide a standard means of notifying objects that they are no longer needed. Some objects ask other entities (which may or may not even be on the same computer!) to do things on their behalf until further notice. When an object is told that it is no longer needed, it can notify any entities that may be acting on its behalf that they no longer need to do so.
As a simple example, creating a file object may (indirectly) cause a request to be sent out to a file server to open a particular file for exclusive access. Until the file server receives a request to close the file, it will not allow anyone else in the known universe to access it. As long as the file object is needed, it will maintain exclusive access to the file. If IDisposable.Dispose is called on the file object, it will (again, indirectly) cause a "close" request to be sent to the file server, thus allowing other programs and computers to access the file.
Note that if the file object were simply to disappear without notifying anyone that the previously-granted exclusive file access was no longer needed, the server might never let anyone else use the file. To protect against this type of problem, the file object's class may define a Finalize() handler. Any time the system creates an object of a class which overrides
Object.Finalize()
, the system will add it to a special list of objects with "registered" Finalize handlers. If such an object is abandoned, the garbage-collector will run its Finalize method before it, or any objects to which it holds direct or indirect references, can actually be removed from memory.Note that the purpose of Dispose is not to destroy the file object itself, but rather to allow it to notify the entity was providing exclusive access the file that such access is no longer needed. Calling Dispose on an object whose class overrides
Object.Finalize()
will notify the garbage-collector that it no longer needs to worry about invoking the Finalize method before removing the object from memory, but won't otherwise destroy the object.