2010-11-05 98 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