我见过一些这样的代码(不是在连续的行上,而是在同一个函数范围内):
Dim con1 As SqlConnection
con1 = New SqlConnection
'More code here
con1 = New SqlConnection
con1 = Nothing
我相信这只是一个错误,但我想检查这里是否存在我不知道的阴影形式。第一个con1
变量会发生什么?我认为它是不可访问的,因为没有对该对象的引用。
这里发生了什么事
con1
在该函数的生命周期内指向两个不同的对象。
第一个对象,由第一个创建
con1 = New SqlConnection
在第二个之后不再引用
con1 = New SqlConnection
被执行。
这是内存泄漏吗?
不会。不再引用的对象最终会被处理掉,然后 GC 决定这样做。但是,这是资源泄漏。每次您无法关闭 SQL 连接(假设它已打开而不是刚刚分配),您就会使资源无法重用。GC 会在内存不足时触发,因此最迟在系统内存不足时,您肯定会重新获得未引用对象的内存(此时您还将重新获得 DB 连接)。但是,低资源不会触发 GC。在 GC 决定启动并释放 SqlConnection 对象(包括他们囤积的数据库连接)之前,您可能会完全用完数据库连接。
修复代码
由于必须关闭 SqlConnection 才能释放连接,所以第一个对象将一直徘徊,直到 GC 决定处置它。 这是一件坏事,因为 SQL 连接是一种资源,只应在必要时保留。
在分配新的 SqlConnection 对象之前调用第一个连接的 Close() 会改善这种情况(另外,在离开变量范围之前在第二个实例上调用 Close())。
但是,如果您在代码中的某处遇到异常,而没有适当的异常处理,则在 GC 启动之前,您仍然会留下未处理的对象。始终,始终将异常处理放在管理诸如此类的资源的任何事物周围。
针对这种情况进行异常处理的最佳方法是使用 Using关键字。到目前为止,我从未写过一行 VB.Net,但这是我对您代码的正确版本的尝试:
Dim con1 As SqlConnection
Using con1
con1 = New SqlConnection
End Using
'More code here
Using con1
con1 = New SqlConnection
End Using
' NOTE: I believe the following is unnecessary, but was necessary in VB6 and prior
' con1 = Nothing