C# 静态成员是否曾经被垃圾收集?

C# 静态成员是否曾经被垃圾收集?,c#,garbage-collection,static-members,C#,Garbage Collection,Static Members,静态成员变量是否曾经被垃圾回收 例如,让我们使用下面的类 public class HasStatic { private static List<string> shared = new List<string>(); } 当a、b、c和d被垃圾收集时,静态成员shared也会被垃圾收集吗?e是否可能获取共享的新实例?否,静态成员与类型关联,该类型与加载它的AppDomain关联 请注意,对于要初始化的类和要引用列表的共享变量,不必有任何HasStatic实

静态成员变量是否曾经被垃圾回收

例如,让我们使用下面的类

public class HasStatic {
    private static List<string> shared = new List<string>();

}

a
b
c
d
被垃圾收集时,静态成员
shared
也会被垃圾收集吗?
e
是否可能获取
共享的新实例?

否,静态成员与类型关联,该类型与加载它的AppDomain关联

请注意,对于要初始化的类和要引用
列表的
共享
变量,不必有任何
HasStatic
实例


除非您考虑卸载AppDomains的情况,否则静态变量可以永远视为GC根。(当然,如果有什么东西改变了HasStatic.shared的值以引用不同的实例,那么第一个实例可能就有资格进行垃圾收集。)

我唯一要补充的是Jon的优秀答案是CLR 4支持“可收集的程序集”。如果动态生成可回收程序集,则当程序集被垃圾回收时,其类型的静态将消失

有关此功能的简要概述,请参阅此msdn文章:


+1。我对此非常确定,但需要测试来验证。。。甚至可以在我的深度书籍中查找!但有两个例外情况需要提及。通过
WeakReference
引用的任何内容都可以被垃圾收集,线程终止的任何实例化为
ThreadLocal
的静态成员也是如此。我知道这是一个非常古老的答案,但我还有一个后续问题,Jon:根据你在括号中的最后一句话:什么决定原始实例是否符合垃圾收集的条件?@ChrisRidge:与其他任何内容相同:基本上,是否有任何方法可以到达对象。如果你将静态成员设置为
null
?从我所阅读的内容来看,这将使其可用于GC。请记住,
a.shared[1]
将具有与
b.shared[1]
相同的值,并且
HasStatic
的这个元素也可以通过
HasStatic.shared[1]
引用。(当然,假设
shared
列表中至少有2个元素。)这些元素在实践中的效果如何?难道没有很多(用户)代码缓存反射数据,从而使类型和程序集保持活动状态吗?哇。。。以前从没听说过这些。学习新东西总是很好。@CodeInChaos:如果用户代码缓存的数据使一个更大的对象保持活动状态,那么系统就会工作。这就是垃圾收集的全部目的,就是让可访问的东西保持活力。可收集程序集的理由是相反的问题:我们希望能够在临时程序集中生成临时代码,这些代码在无法访问时就会消失。在可回收程序集之前,我们无法做到这一点。我的意思是,代码通过缓存类型相关的信息(一旦类型不再存在,这些信息就会过时),意外地使可回收程序集保持活动状态。我提出了一个问题,因为这有点太复杂,无法在评论中讨论:@Eric:那么,WeakReferences和ThreadLocal成员也值得一提。
//Startup
{
HasStatic a = new HasStatic();
HasStatic b = new HasStatic();
HasStatic c = new HasStatic();
HasStatic d = new HasStatic();
//Something
}
//Other code
//Things deep GC somewhere in here
HasStatic e = new HasStatic();