大家好:假设我得到了A级和B级:
class A {
public string foo = "foo";
public int a = 10;
public double d = 3.14;
}
class B {
public string s;
}
A a = new A();
B b = new B();
b.s = a.foo;
a = null;
// if GC occurs here...
我的问题是在 a 设置为null之后,是否可以在下一个GC触发点收集GC,即使b引用其中一个字段,foo?
感谢您的回答。
答案 0 :(得分:4)
我的问题是在a设置为null之后,是否可以在下一个GC触发点由GC收集,即使b引用其中一个字段,foo?
b.s
的值已设置为a.foo
,但这只是复制该值。分配发生后,A
和B
的实例之间绝对没有联系。特别是,a.foo
的所有更改都不会通过b.s
显示。
所以是的,A
的实例可以被垃圾收集。
现在,我怀疑有人可能会谈论string
是不可变的。虽然这是事实,但它实际上并没有影响事物。假设我们有:
class A
{
// We would never really use public fields, of course...
public StringBuilder x;
}
class B
{
public StringBuilder y;
}
然后:
A a = new A();
a.x = new StringBuilder("Foo");
B b = new B();
b.y = a.x;
b.y.Append("Bar");
Console.WriteLine(a.x); // Prints FooBar
a = null;
仍然,B的实例不会阻止A的实例被垃圾收集 - 因为再次,赋值刚刚将值从a.x
复制到b.y
。该值是对StringBuilder
的引用,因此通过任一字段修改StringBuilder
的内容会导致通过其他字段显示的更改,但字段实际上不是&# 34;知"关于彼此。
答案 1 :(得分:1)
B
s
字段引用A
的{{1}}字段而不是foo
的实例, A
A
字段是foo
的一个实例。 string
会在某个时候销毁它,但我们并不确切知道何时(但它会)。如果您希望立即执行此过程,请强制GC
GC
运行GC.Collect()
。 A
的实例将被销毁。
我现在正在研究一个例子来证明我的答案。 -Nevermind,Jon Skeet在这里:)