Ricky
Ricky

Reputation: 35863

Whether the object can be collected by GC

Hi all: assuming I got the Class A and 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...

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?

Thanks for any answer.

Upvotes: 0

Views: 66

Answers (2)

Fatih Mar
Fatih Mar

Reputation: 2500

B's s field referencing A's foo field not A's instance, also A's foo field is an instance of string. GC will destroy it sometime but we don't know exactly when (but it'll). If you want this process immediately, force run GC by GC.Collect(). A's instance will be destroyed.

I'm working on an example now to prove my answer. -Nevermind, Jon Skeet here :)

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500873

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?

The value of b.s happens to have been set to a.foo, but that's just copying the value. After the assignment occurs, there's absolutely no connection between the instances of A and B. In particular, any changes to a.foo won't be visible via b.s.

So yes, the instance of A can be garbage collected.

Now, I suspect someone may talk about string being immutable. While this is true, it doesn't actually affect things. Suppose we had:

class A
{
    // We would never really use public fields, of course...
    public StringBuilder x;
}

class B
{
    public StringBuilder y;
}

Then:

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;

Still, the instance of B does not prevent the instance of A from being garbage collected - because again, assignment has just copied the value from a.x to b.y. That value is a reference to the StringBuilder, so modifying the contents of the StringBuilder via either field results in a change that is visible via the other field, but the fields don't actually "know" about each other.

Upvotes: 4

Related Questions