0
votes

Suppose I have Two Objects:

object1, object2

When I do the following assign:

object2.Foo = object1.Foo; //Edit: where Foo is a reference type

What does the garbage collector do:

  1. Does it collect object1, while perserving the value assigned to object2.Foo?
  2. Or, Does object1 persist until object2 is collected because object2.Foo references object1.Foo?
  3. Or does garbage collection do something completely different, if so please explain?

Thanks!

6
Is Foo an object or a Value type?Henk Holterman
Your question is confusing because it begins with a falsehood. "Suppose I have two objects". OK, which are the two objects? It appears to me that you have four objects -- the object referred to by object1, the object referred to by object2, the object referred to by object1.Foo and the object referred to by object2.Foo. Are there two objects, or four?Eric Lippert

6 Answers

6
votes

The code

object2.Foo = object1.Foo;

has no effect on the status of object1 and object2. It may have an effect for the old value of object2.Foo The object that was referred to by object2.Foo may now be collectable if no other reference to it exists.

3
votes

Assuming Foo is a field or property with a backing store, you will have a graph of objects that resembles this (where references are from left to right):

     object1
    /       \
root         foo
    \       /
     object2

If your last reference to object2 goes out of scope, then you have this:

     object1
    /       \
root         foo
            /
     object2

Anything that is not reachable in the graph of objects from the root is fair game for garbage collection, so object2 can be collected. However, foo is still reachable via object1 and therefore will not be collected.

1
votes

It collects object 1 eventually if there are no more references to the object. Foo is not tied to object1. If Foo is a reference object then it is stored on the heap, and object1 just happens to be storing a pointer to Foo. If Foo were a value type, then a copy is made when you assign it to object2, and object1's Foo is destroyed alongside object1.

An object is destroyed at some point when no more references to the object exist. The only case where objects referenced in a class is destroyed when the class is collected is when the class is the only pointer to the particular reference.

In the below picture you see that even though some objects are extremely old, they don't get collected because they're still referenced. A freshly created object does get GC'ed however due to not being referenced anymore.

alt text
(source: chaoticjava.com)

0
votes

You are just making another reference to Foo. This has nothing to do with object1 at all. Once all of the references to object1 go out of scope, object1 will be collected. Foo is collected completely separately.

EDIT: Assuming foo is a reference type, of course.

0
votes

Object2.Foo and Object1.Foo will reference the same object, that is, the object originally pointed by Object1.Foo. The object previously referenced by Object2.Foo will be collected by garbage collector the next time it runs (this is assuming that Foo's type is a class and not a struct).

0
votes

The answers here seem to miss that if object1.foo used to have an object (and not a null value), whatever was there will be up for garbage collection unless something else (object3.foo?) uses the same object.