请考虑以下代码:
1-...
2-{
3-...
4-SqlConnection cn=new SqlConnection();
5-...
6-}
如果程序达到第 6 条语句会cn
处理?如果不是cn
变量发生了什么?
如果程序达到第 6 条语句,cn 会处理吗?
不。
如果不是 cn 变量发生了什么?
这取决于你以后是否使用它。如果您不使用它并且它超出范围,这意味着它有资格进行垃圾收集。当这种垃圾收集发生时,您无法控制。但是当它发生时,将调用析构函数,它本身调用该Dispose
方法。
话虽这么说,正确的方法是始终将IDisposable
资源包装在using
语句中。这确保了 Dispose 方法将始终被调用,即使抛出异常:
2-{
3-...
4-using (SqlConnection cn=new SqlConnection())
{
...
}
5-...
6-}
不,当 GarbageCollector 决定销毁它时,它将被处置。
如果你想处理它,那么使用using
语句(as SqlConnection
implements IDisposeable
):
using(SqlConnection cn = new SqlConnection())
{
// code
}
不,当变量超出范围时,不会释放对象。
当不再使用对象时(在范围内的某个地方,在使用变量的最后一行之后),该对象就可以进行垃圾回收了。
下次垃圾回收器运行的时候,会发现对象已经没有被使用了,但是它也会发现它有Finalize
方法,并且没有被disdispose,所以会将该对象加入finaliser队列中。此外,由于对象没有被收集,它可能会被移动到下一个堆代,这实际上涉及将对象从内存中的一个位置移动到另一个位置。
垃圾收集器有一个特殊的线程来终结终结器队列中的对象,最终终结对象。对象的方法Finalize
会调用该Dispose
方法,从而关闭数据库连接。
对象被释放后,最终会被垃圾收集器收集。
请注意,无法保证对象将在任何特定时间内完成,甚至根本无法完成。
因此,如果您不处置连接对象,则发生的两件主要事情是:
您应该使用 Using 语句,但结果将是相同的,它不会被丢弃,它将被标记为一次性,并且 GC 将在下次运行时收集它。
没有克雷佐,
1-...
2-{
3-...
4-SqlConnection cn=new SqlConnection();
5-...
6-}
我们编译器到达 Statement cn 对象并没有被破坏。您无法在循环外访问“cn”对象。
如果您使用 Using 块,那么该对象将被自动处理。