对象是否可以被GC回收

Whether the object can be collected by GC

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

感谢您的回答。

Bs 字段引用 Afoo 字段不是 A 的实例,也是 Afoo 字段是 string 的实例。 GC 会在某个时候摧毁它,但我们不知道确切的时间(但它会)。如果您想要立即执行此过程,请将 运行 GC 强制为 GC.Collect()A的实例将被销毁。

我现在正在研究一个例子来证明我的答案。 -没关系,这里是 Jon Skeet :)

My question is after a is set to null, whether it can be collected by GC at next GC trigger point even though b reference one of its fields, 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 的内容会导致通过另一个字段可见的更改,但这些字段实际上并不 "know" 关于彼此。