假设我有两个对象:
object1,object2
当我执行以下操作时:
object2.Foo = object1.Foo; //Edit: where Foo is a reference type
垃圾收集器做什么:
谢谢!
答案 0 :(得分:6)
代码
object2.Foo = object1.Foo;
对object1
和object2
的状态没有影响。它可能对object2.Foo
的旧值有影响。如果不存在对其的任何其他引用,则object2.Foo引用的对象现在可以是可收集的。
答案 1 :(得分:3)
假设Foo
是具有后备存储的字段或属性,您将拥有一个类似于此的对象图(引用从左到右):
object1
/ \
root foo
\ /
object2
如果你对object2
的最后一次引用超出了范围,那么你就有了这个:
object1
/ \
root foo
/
object2
根目录中的对象图中无法访问的任何内容都是垃圾收集的公平游戏,因此可以收集object2
。但是,foo
仍可通过object1
访问,因此无法收集。
答案 2 :(得分:1)
如果没有对该对象的更多引用,它最终会收集对象1。 Foo与object1无关。如果Foo是一个引用对象,那么它存储在堆上,而object1恰好存储了一个指向Foo的指针。如果Foo是值类型,则在将其分配给object2时会生成副本,并且object1的Foo将与object1一起销毁。
当不再存在对象的引用时,某个对象会被销毁。收集类时销毁类中引用的对象的唯一情况是类是唯一指向特定引用的指针。
在下面的图片中,您会看到即使某些对象非常陈旧,也不会被收集,因为它们仍然被引用。然而,由于没有被引用,新创建的对象确实得到了GC。
(来源:chaoticjava.com)
答案 3 :(得分:0)
您只是对Foo
进行了另一次引用。这根本与object1
无关。所有对object1
的引用都超出范围后,将收集object1
。 Foo
完全单独收集。
编辑:当然假设foo
是参考类型。
答案 4 :(得分:0)
Object2.Foo
和Object1.Foo
将引用同一个对象,即Object1.Foo
最初指向的对象。以前由Object2.Foo
引用的对象将在下次运行时由垃圾收集器收集(假设Foo
的类型是类而不是结构)。
答案 5 :(得分:0)
这里的答案似乎错过了如果object1.foo曾经拥有一个对象(而不是一个空值),除非其他东西(object3.foo?)使用相同的对象,否则将会有什么垃圾收集。