如何正确销毁对象,以免造成内存泄漏

时间:2013-02-28 13:09:35

标签: memory-leaks asp-classic vbscript

当我创建两个相互引用的字典对象时,即使我将它们显式设置为空,它们也会保留在内存中。以下代码使用> 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", a更改为a.Add "dict2", "bar"时,内存消耗将保持在合理范围内。

顺便说一下,当字典引用自身时也会发生这种情况:

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

是否有可能以这样的方式销毁像这些交叉引用词典这样的对象?它们也会在内存中被销毁?

2 个答案:

答案 0 :(得分: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 :(得分: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")您必须自己完成。