我一直在读.NET中的垃圾收集,我希望得到一些澄清。所以,据我所知,如果我声明一个公共共享类变量,GC将永远不会摆脱它。这是对的吗?
此外,私有变量是什么?请看以下示例:
public class myClass
private shared myString As String
public sub ChangeString(newString As String)
myString = newString
end sub
end class
如果没有类的实例,共享变量现在会得到GC吗?如果我将ChangeString改为共享子怎么办?
答案 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
来停止引用该对象变量