静态成员的垃圾收集

时间:2009-05-12 06:15:19

标签: .net garbage-collection

垃圾收集器是否会收集静态成员?

4 个答案:

答案 0 :(得分:19)

静态变量引用的对象只会在相关的AppDomain被垃圾回收时进行垃圾回收。在客户端应用程序中,通常只有一个AppDomain在该过程的持续时间内存在。 (例外情况是应用程序使用插件架构时 - 可能会在不同的AppDomain中加载不同的插件,以后可能会卸载AppDomain。)

在ASP.NET中,“AppDomain recycle”会定期发生(由于各种原因) - 当发生这种情况时,AppDomain中的静态变量将不再充当GC根,从而赢得防止物品被垃圾收集。

如果你担心一个对象被垃圾收集而你仍然通过一个静态变量引用它,你可以放松一下。虽然您可以访问该对象,但它不会被垃圾收集。

答案 1 :(得分:5)

不收集成员......对象是。
所以,如果你设置参考。键入static member为null,将收集它之前指向的任何对象。如果没有,它会一直存在,直到AppDomain关闭(每个AppDomain都有自己的一组静态内容)

答案 2 :(得分:2)

简短的答案......不; .NET垃圾收集器的所有当前实现都不会收集由静态类成员字段强引用的对象,直到Application Domain与那些静态类成员字段强引用相关联,才会被拆除。

答案越长......可能是的;垃圾收集器的决定是基于对象的可达性来收集对象,而不是对对象的引用(强或弱)。理论上,如果垃圾收集器可以确定从某个点开始没有代码再次需要某个对象(也就是说,无法从任何代码路径访问该对象),那么GC将被允许收集该对象,甚至如果它仍然被静态类成员字段强烈引用。这是完全允许的,因为您从未注意到,因为没有代码会尝试访问保存对象引用的静态类成员字段。你可能会问,所以为什么我不关心我是否永远不会通过我持有的任何强引用再次访问该对象?你关心的原因是副作用。例如,您可以假设通过为静态类成员字段分配对SafeHandle对象的引用(表示非托管资源),SafeHandle对象永远不会被关闭,从而保持它所代表的非托管“对象”处于活动状态。这仅适用于GC的当前实现。 GC的未来实现可以收集静态类成员字段强烈引用的对象,如果剩余的程序代码不再能够访问这些对象。

答案 3 :(得分:0)

引用类型的静态成员是引用,它可能指向或不指向实例。如果它指向一个实例,则在卸载静态成员之前不会收集所述实例。如果类型加载在特定的AppDomain中,则可以卸载该类型。否则,它仅在应用程序终止时发生。