C#:在什么情况下你应该删除引用?

时间:2009-10-19 06:38:17

标签: c# garbage-collection null reference

  

CLR Profiler还可以显示哪些方法分配的存储空间超出了您的预期,并且可以发现无意中保留对无法通过GC回收的无用对象图的引用的情况。 (一个常见的问题设计模式是一个软件缓存或项目的查找表,这些项目不再需要或以后可以安全重建。当缓存使对象图表保持活动超过其使用寿命时,这是悲剧性的。相反,确保null对不再需要的对象的引用。) - Writing Faster Managed Code

我认为我之前没有真正搞过一个参考文献。我假设你并不总是需要这样做,但我想有时候记得这么做很重要。但是,那是什么情况呢?什么时候应该删除引用?

3 个答案:

答案 0 :(得分:11)

只有当持有引用的变量保持“活动”但您不希望引用本身阻止垃圾回收时,您才需要这样做。换句话说,如果对象A持有对象B的引用,并且您不再需要B,但A将因其他原因而保持活动状态。另一个常见的例子是静态变量,只要AppDomain是“活着的”。

对于局部变量,几乎从不需要,因为GC可以检测代码中最后一个可能访问变量的点。但是,如果您在第一次迭代期间使用在循环外声明的变量,但是您知道在后续迭代中不需要它,那么可以将其设置为null以帮助该对象符合条件GC早些时候。

根据我的经验,在这种情况下发现自己很少非常。为了GC,我几乎没有考虑将变量设置为null。通常,对象中的所有成员变量都是“有用的”,直到对象本身符合GC的条件。如果您发现自己的成员变量对于对象的整个生命周期都不是有用,您可能希望看到这是否表明设计存在问题。

答案 1 :(得分:4)

如果您拥有对短期对象(如缓存项)的引用的长期存在的对象(如引用中的缓存示例),这一点很重要。长生活对象的其他示例可以是单例对象,Windows窗体应用程序中的主窗体实例,ASP.NET应用程序的应用程序实例等。

我想添加另一个常见的pitfull:订阅由长期存在的对象发布的事件的短期对象。由于事件发布者拥有对所有订阅者的引用,因此如果您不取消订阅,则不会收集订阅者(例如,仅需要几毫秒的ASP.NET页面或控件实例)。

答案 2 :(得分:1)

当你知道它们不会被垃圾收集时,你应该删除你不再需要的对象的引用。

如果你有Effective Java书,请看第5项,有一个堆栈实现的例子,它有内存泄漏,因为对象引用没有被删除。如果您没有该图书,则可以在Google图书here上查看该部分。