.net 共享变量和垃圾收集
我一直在读一些关于.NET中垃圾收集的文章,我希望得到一些澄清。因此,据我所知,如果我声明一个公共共享类变量,GC将永远无法摆脱它。这是正确的吗 还有,那么私有变量呢?以以下为例:.net 共享变量和垃圾收集,.net,vb.net,garbage-collection,.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
public class myClass
private shared myString As String
public sub ChangeString(newString As String)
myString = newString
end sub
end class
如果没有该类的实例,共享变量现在会得到GCed吗?如果我将ChangeString更改为一个共享子变量,该怎么办?静态(共享)变量始终被视为根变量。线程静态(共享)变量是所属线程的根。因此,无论这些变量引用什么,GC都永远不会清理它们
如果没有该类的实例,共享变量现在会得到GCed吗
因此,如果调用过静态构造函数,那么引用对象将在相关的生存期内保持不变(对于static,进程为static,对于threadstatic,线程为thread)。不管是否有类的实例,重要的是是否执行了静态构造函数(这有点不确定,您只知道如果需要任何静态成员,它们将在第一次需要之前创建)
如果我将ChangeString更改为一个共享子对象呢
这没关系
因此,据我所知,如果我声明一个公共共享类变量,GC将永远无法摆脱它。这是正确的吗
差不多。GC不会清除共享变量引用的字符串
但是,如果使用新字符串调用ChangeString
,则myString
指向的字符串将不再以该引用为根,并且可能符合GC的条件。但是,新字符串(由newString
引用)现在将由myString
变量根化,从而防止垃圾收集
如果没有该类的实例,共享变量现在会得到GCed吗
不。共享变量是对象的根,因为它属于类的“类型”,而不是任何实例
如果我将ChangeString更改为一个共享子对象呢
这一点都没有影响。共享变量存在于类本身中,因此不需要类的实例来保存该变量,因此不会对字符串进行垃圾收集 不管变量是否私有,它仍然不会被垃圾收集。不管您是使用分片方法还是实例方法来设置变量
注意:垃圾收集器从不收集变量,它只收集对象。
Shared
变量引用以应用程序域为根。因此,只要应用程序域仍然被加载,那么该变量引用的任何对象都仍然是根对象,因此GC将不会收集该对象,无论包含类的实例可能存在或不存在多少。但是,如果更改引用,就像在特定示例中使用ChangeString
所做的那样,那么旧对象将不再是根对象,并且现在可以进行收集
同样,只要您没有执行高级应用程序域管理,那么myString
引用的任何对象都将不符合收集条件,当然,除非您通过重新分配myString
变量停止引用该对象