当前位置:  开发笔记 > 后端 > 正文

是否需要在VBA函数中将对象设置为Nothing

如何解决《是否需要在VBA函数中将对象设置为Nothing》经验,为你挑选了3个好方法。

我总是读到,一旦我完成它们,建议将对象设置为空.但我通常只在表单内的函数中使用它们.

在保留功能范围时,是否丢失了引用并释放了内存,而不管将对象设置为Nothing?

即是否真的有必要这样做:

Set db = Nothing
Set record_set = Nothing

Tomalak.. 73

VB使用所谓的"引用计数"垃圾收集器.

基本上,当变量超出范围时,引用对象上的引用计数器会递减.将对象引用分配给另一个变量时,引用计数器会递增.

当计数器达到零时,该对象已准备好进行垃圾回收.一旦发生这种情况,对象资源就会被释放.函数局部变量很可能引用引用计数永远不会大于1的对象,因此当函数结束时将释放对象资源.

将变量设置为Nothing显式减少引用计数器的方法.

例如,您读入文件,并NothingReadAll()调用后将文件对象变量设置为右侧.文件句柄将立即释放,您可以花时间处理其内容.

如果未设置Nothing,则文件句柄可能会打开超过绝对必要的时间.

如果您没有"必须解锁宝贵的资源"的情况,只需让变量超出范围就可以了.



1> Tomalak..:

VB使用所谓的"引用计数"垃圾收集器.

基本上,当变量超出范围时,引用对象上的引用计数器会递减.将对象引用分配给另一个变量时,引用计数器会递增.

当计数器达到零时,该对象已准备好进行垃圾回收.一旦发生这种情况,对象资源就会被释放.函数局部变量很可能引用引用计数永远不会大于1的对象,因此当函数结束时将释放对象资源.

将变量设置为Nothing显式减少引用计数器的方法.

例如,您读入文件,并NothingReadAll()调用后将文件对象变量设置为右侧.文件句柄将立即释放,您可以花时间处理其内容.

如果未设置Nothing,则文件句柄可能会打开超过绝对必要的时间.

如果您没有"必须解锁宝贵的资源"的情况,只需让变量超出范围就可以了.


虽然你写的所有内容都是真实的(并且说得好),但问题是标记为MS Access,这意味着VBA.Access中的VBA历来存在未正确更新引用计数的问题,因此建议明确清理对象变量.
知识库文章并未指出MS Access中存在不同的垃圾收集器.它指的是DAO的特性,或者在Access和DAO的紧密连接中,只有当Access用作自动化服务器时才会出现.
我不知道VBA和VB 6.0在这方面有任何可见的区别.我不敢相信他们为MS Access编写了一个新的垃圾收集器和一个新的VB运行时.
这有什么权威吗?我当然可以相信GC系统中可能存在错误,因此无法正确识别对象何时符合GC条件.但问题是,VB中是否存在一个错误,即超出范围的变量不会正确地减少使用计数,但是将变量设置为空可以正确地减少使用计数.我对编程方法持怀疑态度,他说:"好吧,编译器可能会生成错误的代码,所以我会写一堆额外的代码以防万一." 这会在哪里......
@Tomalak我回复了评论,而不回答你的回答.:-)

2> BIBD..:

垃圾收集很少是完美的.即使在.NET中,也有时强烈建议您尽早提示系统进行垃圾收集.

出于这个原因,当我完成它们时,我明确地关闭并设置为Nothing记录集.


你的意思是.NET垃圾收集并不完美,因为它的设计并不总是最优或者设计中存在缺陷吗?您是否有任何参考资料解释了建议您提前收集的情况?谢谢.

3> Shane Miskin..:

Microsoft DAO帮助和Access Developer Reference中" Recordset.Close " 帮助主题的最后一行是:

"Close方法的替代方法是将对象变量的值设置为Nothing(Set 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方法.我没有对它进行任何测试,但似乎并不重要.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有