我的一位同事声称,在非静态类中使用静态成员的C#可以防止这些类的实例被垃圾收集,并且这是C#内存泄漏的常见来源。因此,他总是将静态成员包装在静态类中,并通过该静态类上的静态属性或方法从那里获取对它们的访问权限。我一直认为静态是在堆栈上,而不是堆,因此与垃圾收集没有任何关系。这对我来说似乎不对。
这是关于什么的真相?
答案 0 :(得分:10)
他不知道他在说什么。非静态类中的静态成员不阻止类的实例被垃圾回收。
也就是说,静态可以在堆栈或堆上。垃圾收集无关紧要。重要的是类型的静态部分不与类型的实例一起存储。
答案 1 :(得分:5)
静态成员是GC的根。从静态引用的任何内容都将保持活动状态。静态引用是在静态类中还是在非静态类中是无关紧要的。
如果你有一个非静态类,它有一个静态字段,并且你有该类的实例,那么静态字段没有很多实例 - 这是static定义的一部分 - 它不是每个实例字段。因此,班级本身是否是静态的,没有任何区别。
所以,是的,静态引用通常是内存泄漏的原因,尤其是在适当的时候没有取消订阅的静态事件。将类更改为静态不会解决内存泄漏问题 - 您需要在其引用的实例的生命周期结束时删除静态引用。通常这是通过Dispose()对象并让Dispose清理引用/事件订阅来完成的。
This是了解GC如何工作,如何识别垃圾及其作用的好地方。除了终结者还有更多...
答案 2 :(得分:0)
你的朋友不对。
静态方法的想法是该类没有实例。所以垃圾收集什么也没有。
尝试将this
放在非静态类中的静态方法中,看看会发生什么。