是否需要在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