是否需要在VBA函数中将对象设置为Nothing
我总是读到,一旦我完成了它,build议将对象设置为无。 但是我通常只在表单里面使用它们。
当函数作用域保留时,是不是引用丢失和内存释放,而不pipe将对象设置为Nothing?
即真的有必要这样做:
Set db = Nothing Set record_set = Nothing
VB使用所谓的“引用计数”垃圾收集器。
基本上,当一个variables超出范围时,被引用对象上的引用计数器递减。 将对象引用分配给另一个variables时,引用计数器递增。
当计数器达到零时,对象已准备好进行垃圾收集。 对象资源将在发生这种情况时立即释放。 函数局部variables很可能会引用其参考计数永远不会高于1的对象,因此在函数结束时将释放对象资源。
将variables设置为Nothing
是显式减less引用计数器的方法。
例如,读取文件,并在ReadAll()
调用之后将文件对象variables设置为Nothing
。 文件句柄将立即释放,您可以花时间处理其内容。
如果您没有设置为Nothing
,则文件句柄可能会打开超过绝对必要的时间。
如果你不在“必须打开宝贵的资源”的情况下,简单地让variables超出范围是没问题的。
垃圾收集很less完美。 即使在.NET中,也有时候强烈build议您尽早提前系统进行垃圾回收。
出于这个原因,当我完成它们时,我明确地closures并设置为Nothinglogging集。
Microsoft DAO帮助和Access开发人员参考中的“ Recordset.Close ”帮助主题的最后一行是这样的:
“Close方法的替代方法是将对象variables的值设置为Nothing(Set dbsTemp = Nothing)。”
http://msdn.microsoft.com/en-us/library/bb243098.aspx
考虑到这一点,Microsoft知识库中的这篇文章标题为“如何在使用数据访问对象(DAO)后防止数据库膨胀”,告诉您如果不希望数据库膨胀,则应该显式closures。 你会注意到这篇文章对细节有些模糊, “原因”一节尚不清楚,几乎到了乱七八糟的地步。
http://support.microsoft.com/kb/289562
症状:实现数据访问对象(DAO)以打开logging集后,Microsoft Access数据库已经开始膨胀(或快速增长的大小)。
原因:如果每次循环访问logging集代码时都不释放logging集的内存,DAO可能会重新编译,使用更多内存并增加数据库的大小。
更多信息当您在代码中创buildRecordset(或QueryDef)对象时,显式closures完成后的对象。 在大多数情况下,Microsoft Access会自动closuresRecordset和QueryDef对象。 但是,如果您明确地closures代码中的对象,则可以避免在对象保持打开状态时偶尔出现的情况。
最后,让我补充一点,我已经使用了Access数据库15年了,而且我几乎总是让我的本地声明的logging集variables超出范围而不明确使用Close方法。 我没有做任何testing,但似乎并不重要。
当variables超出范围时,引用应该被清除。 大概这个软件的后期版本有所改进,但是一度不可靠。 我相信将variables明确地设置为“Nothing”仍然是一个好的做法。
当你使用ASP classic(服务器端脚本)的时候,当你使用ASP时,将所有的对象设置为空,因为直到[虚拟]服务器closures,它们才会超出范围。
为此,所有MS VB脚本示例总是显示对象被closures并设置为空。 这样,脚本摘录就可以用在ASP经典的对象没有超出范围的环境中。
很less有其他情况下,您希望编写对象不超出范围的长时间运行的进程,并且如果不显式释放对象,则发现自己的物理内存不足。
如果你发现你自己编写了ASP classic,或者出于某种其他原因在全局范围内运行进程,那么是的,你应该明确地释放对象。
我通常总是把这个放在我的程序的最后,或者在我使用模块级的时候调用一个“CloseRecordSet”的sub:
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
然而,这样的方式结束,(通常是或由于错误)对象被清理和资源是免费的。
这样做是相当安全的,因为它可以轻而易举地完成closures,或销毁logging集/连接对象所必需的事情,因为它已经被closures(由于运行时错误或只是应该尽早closures它,这只是确保)。
它没有太多的麻烦,它总是最好的清理你的对象,当你完成他们立即释放资源,无论程序中发生了什么。
尝试这个
If Not IsEmpty(vMyVariant) Then Erase vMyVariant vMyVariant = Empty End If