是否可以通过GC收集对象

时间:2015-07-17 07:10:55

标签: c# .net garbage-collection

大家好:假设我得到了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?

感谢您的回答。

2 个答案:

答案 0 :(得分:4)

  

我的问题是在a设置为null之后,是否可以在下一个GC触发点由GC收集,即使b引用其中一个字段,foo?

b.s 的值已设置为a.foo,但这只是复制该值。分配发生后,AB的实例之间绝对没有联系。特别是,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在这里:)