我总是读到,一旦我完成了对象,建议将对象设置为空。但我通常只在表格内的函数中使用它们。
在保留函数范围时是否丢失了引用并释放了内存,而不管将对象设置为Nothing?
即。是否真的有必要这样做:
Set db = Nothing
Set record_set = Nothing
答案 0 :(得分:71)
VB使用所谓的“引用计数”垃圾收集器。
基本上,当变量超出范围时,引用对象上的引用计数器会递减。将对象引用分配给另一个变量时,引用计数器会递增。
当计数器达到零时,该对象已准备好进行垃圾回收。一旦发生这种情况,对象资源就会被释放。函数局部变量很可能引用一个引用计数永远不会大于1的对象,因此当函数结束时将释放对象资源。
将变量设置为Nothing
是明确减少参考计数器的方法。
例如,您读入文件,并在Nothing
调用后立即将文件对象变量设置为ReadAll()
。文件句柄将立即释放,您可以花时间处理其内容。
如果未设置为Nothing
,则文件句柄可能会打开超过绝对必要的时间。
如果您不是“必须解锁宝贵资源”的情况,只需让变量超出范围即可。
答案 1 :(得分:14)
垃圾收集很少是完美的。即使在.NET中,也有时强烈建议您尽快提示系统进行垃圾收集。
出于这个原因,我完成了关闭并设置为 Nothing 记录集。
答案 2 :(得分:12)
Microsoft DAO帮助和Access Developer Reference中“Recordset.Close”帮助主题的最后一行是:
“Close方法的替代方法是 设置对象变量的值 没什么(设置dbsTemp = Nothing)。“
http://msdn.microsoft.com/en-us/library/bb243098.aspx
考虑到这一点,来自Microsoft知识库的this article标题为“如何在使用数据访问对象(DAO)后防止数据库膨胀”,告诉您如果不需要,则应明确关闭数据库膨胀。你会注意到这篇文章对细节有点模糊; “原因”部分尚不清楚,几乎到了胡言乱语的程度。
http://support.microsoft.com/kb/289562
症状:Microsoft Access数据库 已经开始膨胀(或迅速增长) 在实现数据访问之后 对象(DAO)打开记录集。
原因:如果你没有发布 每次你记录集的记忆 循环遍历记录集代码,DAO 可以重新编译,使用更多的内存和 增加数据库的大小。
更多信息:创建时 Recordset(或QueryDef)对象 代码,显式关闭对象时 你完蛋了。 Microsoft Access 自动关闭Recordset和 QueryDef对象最多 情况。但是,如果你 明确关闭你的对象 代码,你可以避免偶尔 对象保留的实例 开。
最后,让我补充一点,我已经使用Access数据库15年了,而且我几乎总是让我的本地声明的记录集变量超出范围而不显式使用Close方法。我没有对它进行任何测试,但似乎并不重要。
答案 3 :(得分:2)
当变量超出范围时,应该清理引用。据推测,随着软件的更新版本的改进,这种情况有所改善,但有一段时间不可靠。我认为将变量明确设置为“Nothing”仍然是一种很好的做法。
答案 4 :(得分:2)
当您使用ASP classic(服务器端脚本)时,在使用它们时将所有对象设置为空是导入的,因为它们在[虚拟]服务器关闭之前不会超出范围。
出于这个原因,所有MS VB脚本示例始终显示对象被关闭并设置为空。因此,脚本摘录可以在ASP经典的环境中使用,其中对象不会超出范围。
在很少有其他情况下,您希望编写长时间运行的进程,其中对象不会超出范围,如果您没有显式释放对象,则会发现自己的物理内存不足。
如果您发现自己编写ASP经典编码,或者出于其他原因在全局范围内运行进程,那么是的,您应该明确地释放对象。
答案 5 :(得分:1)
我通常总是把它放在我的程序的末尾,或者如果我使用的是模块级的那个,则用它调用“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
然而,程序结束,(无论是正常还是由于错误),对象被清理并且资源是免费的。
这样做是非常安全的,因为它你可以把它打开并且它只会做关闭或破坏记录集/连接对象的必要条件,因为它已经被关闭(由于运行时错误或只是提早关闭它,这只是确保)。
它真的没那么麻烦,当你完成它们时,它总是最好清理你的对象,以便不管程序中发生什么,都可以立即释放资源。
答案 6 :(得分:-1)
试试这个
If Not IsEmpty(vMyVariant) Then
Erase vMyVariant
vMyVariant = Empty
End If