【问题标题】:Shared Variables and Garbage Collection共享变量和垃圾收集
【发布时间】:2012-02-21 18:00:26
【问题描述】:

我一直在阅读 .NET 中的垃圾收集,希望得到一些澄清。因此,据我所知,如果我声明一个公共共享类变量,GC 将永远不会摆脱它。这是正确的吗?

另外,私有变量呢?举个例子:

public class myClass
    private shared myString As String

    public sub ChangeString(newString As String)
        myString = newString
    end sub
end class

如果没有类的实例,共享变量现在会被 GC 吗?如果我将 ChangeString 更改为共享子怎么办?

【问题讨论】:

    标签: .net vb.net garbage-collection


    【解决方案1】:

    所以,据我所知,如果我声明一个公共共享类变量,GC 永远不会摆脱它。这是正确的吗?

    几乎。 GC 不会清理共享变量引用的字符串。

    但是,如果您使用新字符串调用 ChangeString,则 myString 指向的字符串将不再以此引用为根,并且可能符合 GC 条件。但是,新字符串(由newString 引用)现在将被myString 变量作为根,从而阻止它进行垃圾回收。

    如果没有类的实例,共享变量现在会被 GC 吗?

    没有。共享变量是对象的根,因为它属于类的“类型”,而不是任何实例。

    如果我将 ChangeString 更改为共享子会怎样?

    这完全没有效果。

    【讨论】:

      【解决方案2】:

      共享变量存在于类本身中,因此您不需要类的实例来使变量存在,因此您的字符串不会被垃圾收集。

      变量是否私有无关紧要,它仍然不会被垃圾收集。使用分片方法或实例方法来设置变量都没有关系。

      注意:垃圾收集器从不收集变量,它只收集对象。

      【讨论】:

        【解决方案3】:

        静态(共享)变量始终被视为根。线程静态(共享)变量是拥有线程的根。因此,这些变量所指的任何内容都不会被 GC 清理。

        如果没有类的实例,共享变量现在会被 GC 吗?

        因此,如果调用了静态构造函数,则引用对象将在相关生命周期内持续存在(静态的进程和线程静态的线程)。是否存在类的实例并不重要,重要的是静态构造函数是否执行(这有点不确定,您只知道如果需要任何静态成员,它们将在之前创建第一次需要它们)。

        如果我将 ChangeString 更改为共享子会怎样?

        这没关系。

        【讨论】:

          【解决方案4】:

          Shared 变量引用植根于应用程序域。因此,只要应用程序域仍然加载,那么该变量引用的任何对象仍然是根的,因此无论包含类的多少实例可能存在或可能不存在,GC 都不会收集该对象。但是,如果您更改引用,就像在您的特定示例中使用 ChangeString 所做的那样,那么旧对象将不再是根对象,现在可以被收集。

          同样,只要您不进行高级应用程序域管理,那么 myString 引用的任何对象都将不符合收集条件,当然,除非您通过重新设置 myString 变量来停止引用该对象。

          【讨论】:

            猜你喜欢
            • 2011-06-07
            • 2019-02-22
            • 1970-01-01
            • 2017-08-22
            • 2012-03-21
            • 1970-01-01
            • 2011-05-07
            • 1970-01-01
            • 2012-03-21
            相关资源
            最近更新 更多