GC如何处理.net平台上的这个问题?

时间:2011-06-09 10:27:45

标签: c# .net clr

我有这段代码

 classObject var1 = new classObject();
 classObject var2 = var1;

现在,我写了这个:

 var1 = null;

GC将如何处理? GC会收集这个classObject的实例吗?

如果我写了var2 = null,GC将如何处理这个问题? (并从代码中删除var1 = null)

5 个答案:

答案 0 :(得分:8)

简答:不,因为var2仍然引用了实例。只要您至少有一个对象的引用,就不会收集该对象。

更长的答案:实际上,可能在这个例子中,因为你不会继续对var2做任何事情。 GC考虑了可变的活跃度。如果你从不在代码中再次使用var2,那么在那最后一行代码之后,var2被认为不是活的。因此,这样的引用被认为对垃圾收集目的没有意义 - 就好像var2不再存在一样。事实上,该对象将有资格收集:

其他细微之处:它还取决于您是在调试模式还是在发布模式下运行。在调试时,.NET会人为地扩展变量的活跃度,以扩展到词法范围的末尾,这样您就有机会检查局部变量。此外,只有当GC实际运行时才会收集对象。

严格来说,实际上不可能给出普遍正确的答案。

答案 1 :(得分:4)

不,因为您仍然在var2中有对象的实时引用。如果您将var1var2都归零,则它将有资格进行收集(假设不存在其他参考)。

答案 2 :(得分:4)

您仍然可以引用该对象(var2)。

这一切都取决于具体情况。

即使您仍然引用了某个对象,GC也可以收集对象(如果它确定该对象在代码中不会被更多地使用)

有趣的阅读:http://www.theserverside.net/tt/articles/showarticle.tss?id=GarbageCollection

更新

对我来说,这听起来像是让参考类型混淆了值类型。分配变量时,不是将实际对象分配给它,而是分配引用。如果某个地方的某个变量会引用它,那么GC(大多数情况下)都不会收集对象。

以下文章显示了差异:http://www.albahari.com/valuevsreftypes.aspx

答案 3 :(得分:2)

您只是将指针var1设置为null var2仍然指向classObject,因此GC不会收集classObject直到至少有一个classObject的引用存活

答案 4 :(得分:1)

垃圾收集通过查看堆栈来确定堆上的对象是否具有实时引用。如果堆栈上没有引用堆上的对象,则它有资格进行垃圾回收。

你可以多次重新分配引用,只要一个对象可以从栈中访问,就不会被垃圾回收!