共享变量和垃圾收集

时间:2012-02-21 18:00:27

标签: .net vb.net garbage-collection

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

此外,私有变量是什么?请看以下示例:

public class myClass
    private shared myString As String

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

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

4 个答案:

答案 0 :(得分:5)

  

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

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

但是,如果使用新字符串调用ChangeString,则myString指向的字符串将不再受此引用的影响,并且可能符合GC的条件。但是,新字符串(由newString引用)现在将由myString变量生根,从而防止垃圾收集。

  

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

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

  

如果我将ChangeString改为共享子怎么办?

这根本没有效果。

答案 1 :(得分:2)

静态(共享)变量始终被视为根。线程静态(共享)变量是拥有线程的根。因此,无论这些变量引用什么,都不会被GC清理。

  

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

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

  

如果我将ChangeString改为共享子怎么办?

这没关系。

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

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

同样,只要您没有进行高级应用程序域管理,那么myString引用的任何对象都将无法进行收集,除非您通过重新分配myString来停止引用该对象变量