我总是读到,建议在完成对对象的设置后,将其设置为空。但是我通常只在表单内部的函数中使用它们。
无论将对象设置为Nothing,在离开函数作用域时是否都不会丢失参考并释放内存?
即是否真的有必要做:
Set db = Nothing
Set record_set = Nothing
Answers:
VB使用所谓的“引用计数”垃圾收集器。
基本上,当变量超出范围时,所引用对象上的引用计数器就会递减。当将对象引用分配给另一个变量时,引用计数器将增加。
当计数器达到零时,该对象已准备好进行垃圾回收。一旦发生这种情况,对象资源将被释放。函数局部变量很可能会引用其引用计数永远不会超过1的对象,因此在函数结束时将释放对象资源。
将变量设置为Nothing
是显式减少参考计数器的方法。
例如,您读入一个文件,并将文件对象变量设置Nothing
为ReadAll()
调用。文件句柄将立即释放,您可以花些时间处理其内容。
如果未设置为Nothing
,则打开文件句柄的时间可能超过绝对必要的时间。
如果您不在“必须释放有价值的资源”这种情况下,只需让变量超出范围就可以。
垃圾收集很少是完美的。即使在.NET中,有时也强烈建议您提示系统提早进行垃圾收集。
由于这个原因,当我处理完它们时,我会同时明确关闭并设置为Nothing记录集。
Microsoft DAO帮助和Access Developer参考中的“ Recordset.Close ”帮助主题的最后一行是这样的:
“ Close方法的一种替代方法是将对象变量的值设置为Nothing(设置dbsTemp = Nothing)。”
http://msdn.microsoft.com/en-us/library/bb243098.aspx
考虑到这一点,本文有权从Microsoft知识库“如何防止数据库膨胀您使用后的数据访问对象(DAO)”,告诉你,你应该明确地接近,如果你不想让你的数据库膨胀。您会注意到该文章对细节有些含糊。“原因”部分尚不清楚,几乎是乱码。
http://support.microsoft.com/kb/289562
症状:在实现数据访问对象(DAO)以打开记录集后,Microsoft Access数据库已开始膨胀(或大小快速增长)。
原因:如果您没有在每次遍历记录集代码时都释放记录集的内存,则DAO可能会重新编译,使用更多的内存并增加数据库的大小。
更多信息:当您在代码中创建一个Recordset(或QueryDef)对象时,完成后显式关闭该对象。在大多数情况下,Microsoft Access会自动关闭Recordset和QueryDef对象。但是,如果在代码中显式关闭对象,则可以避免在对象保持打开状态时偶尔出现实例。
最后,让我补充说,我已经使用Access数据库已有15年了,并且几乎总是让本地声明的记录集变量超出范围,而无需显式使用Close方法。我没有对其进行任何测试,但这似乎无关紧要。
我通常总是将其放在过程的末尾,或者如果我使用模块级的,则在其中调用“ CloseRecordSet”子句:
Private Sub Rawr()
On Error GoTo ErrorHandler
'Procedural Code Here.
ExitPoint:
'Closes and Destroys RecordSet Objects.
If Not Recset Is Nothing Then
If Recset.State = 1 Then
Recset.Close
Conn.Close
End If
Set Recset = Nothing
Set Conn = Nothing
End If
Exit Sub
ErrorHandler:
'Error Handling / Reporting Here.
Resume ExitPoint
End Sub
这样,过程结束了(无论是正常还是由于错误),对象将被清理,资源将被释放。
这样做很安全,因为您可以将其拍一下,并且只会关闭或销毁记录集/连接对象,如果它已经关闭(由于运行时错误或只需尽早关闭它,就可以确定)。
确实没什么麻烦,而且当您完成对象的清理以立即释放资源时,无论程序中发生了什么,清理对象始终是最好的。
尝试这个
If Not IsEmpty(vMyVariant) Then
Erase vMyVariant
vMyVariant = Empty
End If