2013-02-28 86 views
2

當我創建兩個彼此相互引用的字典對象時,即使將其明確設置爲空,它們仍留在內存中。以下代碼消耗> 1 GB的內存如何正確銷燬對象,以免造成內存泄漏

Dim i 
For i = 1 to 100000 
    leak 
Next 

Sub leak 

    Dim a, b 
    Set a = createObject("scripting.dictionary") 
    Set b = createObject("scripting.dictionary") 

    a.Add "dict1", b 
    b.Add "dict2", a 

    Set a = Nothing 
    Set b = Nothing 

end sub 

這與某些垃圾收集無關(VBScript不這樣做)。證明:當我將a.Add "dict1", b更改爲a.Add "dict1", "foo"b.Add "dict2", aa.Add "dict2", "bar"時,內存消耗保持在合理範圍內。

順便說一句,這也是當字典引用本身發生:

Sub leak 
    Dim a 
    Set a = createObject("scripting.dictionary") 
    a.Add "dict1", a 
    Set a = Nothing 
end sub 

是否有可能摧毀這樣的交叉的方式,他們也被破壞內存中引用字典對象?

回答

2

找到了詞典的答案:使用RemoveAll方法在引用超出作用域之前擺脫所有鍵和值。測試它並沒有泄漏:

Sub leak 

    Dim a, b 
    Set a = createObject("scripting.dictionary") 
    Set b = createObject("scripting.dictionary") 

    a.Add "dict1", b 
    b.Add "dict2", a 

    a.RemoveAll 
    b.RemoveAll 

end sub 

,如果你使用字典作爲keys(而不是items/values)這也解決了循環引用的問題,如:

a.Add b, "dictionary b" 
b.Add a, "dictionary a" 
1

首先閱讀Eric Lippert's article (Explanation #2),然後更改您的代碼

Dim i 
For i = 1 to 100000 
    leak 
Next 

Sub leak 

    Dim a, b 
    Set a = createObject("scripting.dictionary") 
    Set b = createObject("scripting.dictionary") 

    a.Add "dict1", b 
    b.Add "dict2", a 

    Set a("dict1") = Nothing 
    Set b("dict2") = Nothing 

end sub 

ab的引用計數由離開子範圍遞減,對a("dict1")b("dict2")你必須自己做。

+0

好文章!感謝這一點,我找到了解決方案:在讓字典超出範圍之前,使用'x.RemoveAll'去除所有密鑰,然後我將發佈解決方案。 – AutomatedChaos 2013-02-28 13:55:48