我有这段代码
classObject var1 = new classObject();
classObject var2 = var1;
现在,我写了这个:
var1 = null;
GC将如何处理? GC会收集这个classObject的实例吗?
如果我写了var2 = null,GC将如何处理这个问题? (并从代码中删除var1 = null)
答案 0 :(得分:8)
简答:不,因为var2仍然引用了实例。只要您至少有一个对象的引用,就不会收集该对象。
更长的答案:实际上,可能在这个例子中,因为你不会继续对var2做任何事情。 GC考虑了可变的活跃度。如果你从不在代码中再次使用var2,那么在那最后一行代码之后,var2被认为不是活的。因此,这样的引用被认为对垃圾收集目的没有意义 - 就好像var2不再存在一样。事实上,该对象将有资格收集:
其他细微之处:它还取决于您是在调试模式还是在发布模式下运行。在调试时,.NET会人为地扩展变量的活跃度,以扩展到词法范围的末尾,这样您就有机会检查局部变量。此外,只有当GC实际运行时才会收集对象。
严格来说,实际上不可能给出普遍正确的答案。
答案 1 :(得分:4)
不,因为您仍然在var2
中有对象的实时引用。如果您将var1
和var2
都归零,则它将有资格进行收集(假设不存在其他参考)。
答案 2 :(得分:4)
您仍然可以引用该对象(var2
)。
这一切都取决于具体情况。
即使您仍然引用了某个对象,GC也可以收集对象(如果它确定该对象在代码中不会被更多地使用)
有趣的阅读:http://www.theserverside.net/tt/articles/showarticle.tss?id=GarbageCollection
对我来说,这听起来像是让参考类型混淆了值类型。分配变量时,不是将实际对象分配给它,而是分配引用。如果某个地方的某个变量会引用它,那么GC(大多数情况下)都不会收集对象。
答案 3 :(得分:2)
您只是将指针var1
设置为null
var2
仍然指向classObject
,因此GC
不会收集classObject
直到至少有一个classObject
的引用存活
答案 4 :(得分:1)
垃圾收集通过查看堆栈来确定堆上的对象是否具有实时引用。如果堆栈上没有引用堆上的对象,则它有资格进行垃圾回收。
你可以多次重新分配引用,只要一个对象可以从栈中访问,就不会被垃圾回收!