2010-11-05 94 views
18

我发现自己最近不得不编写一些VBA代码,只是想知道是否有人遇到过有关VBA垃圾收集器如何工作的任何细节? .Net GC确实有很好的文档记录,但我无法在VBA GC上找到一个细节,除了模糊地提到它是参考计数器。我认为它与VB6 GC非常相似,但无法找到任何信息。VBA垃圾收集器详细信息

具体来说,我有兴趣知道:(?是集几代,例如)

  • 什么触发了GC
  • 它使用什么算法
  • 如何(如果有的话)不它处理循环引用?
  • 是否有监控其操作的任何方式

这更多的是出于好奇心比任何特别需要知道,任何有识之士都非常感谢!

+2

Konrad的答案是你所需要的,但我也会指出你的VB程序员指南,特别是关于“对象模型”的部分,它讨论了引用计数,“tearDown方法”等:http:// msdn.microsoft.com/en-us/library/aa263491(v=VS.60).aspx – jtolle 2010-11-05 22:23:38

回答

14

以下假设VBA是仍然使用在VB6中使用相同的垃圾回收机制(它很可能)。

VB6使用了引用计数GC。当给定对象的最后一个引用设置为Nothing时,GC会确定性触发。设置当地引用Nothing是不必要的,这发生在他们超出范围。

每个对象都实现一个COM接口,该接口负责处理该对象的引用计数。对象引用的每个赋值都更新相关引用的引用计数器(即先前引用的旧对象的计数器递减,并且新对象的计数器递增)。一个对象在参考计数器达到0时收集垃圾。

因此循环引用中的对象在VBA应用程序的生命周期中从不收集。更重要的是,VBA不提供打破循环引用的方法。在VB6中,弱引用可以通过WinAPI函数实现。

+1

“将局部引用设置为Nothing是不必要的,这是因为它们超出了范围。” < - 这应该在每个VBA/VB6开发人员的眼皮中纹身! – Lunatik 2010-11-05 13:27:25

+0

@Lunatik - 同意!我在搜索GC信息时发现的帖子数量,这些信息说“最好的做法是将参考文献设置为无”是非常可怕的。 – 2010-11-05 13:55:00

+5

@Jon:不幸的是,这个传言并非完全没有根据。 VB6似乎有一个错误,可能会导致类成员变量中的一些悬而未决的引用(不是本地变量)。我不知道这个错误的确切来源是否被追踪过,但是使用'Class_Terminate'方法将所有成员设置为'Nothing',已经成为一种确定的最佳实践。 – 2010-11-05 13:58:47