views:

198

answers:

6

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!

+1  A: 

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

Qua
That's not quite an accurate description of generational garbage collection, which the comic depicts. A generational garbage collector will mark objects that have survived some number of collection passes (usually just 1 pass) so that it knows not to waste much time collecting them. Most garbage will always be objects that are allocated, used once and no longer needed, and so any objects that outlast a single collection are simply unlikely to be collectable. The garbage collector will still, occasionally check old objects for collectability, just not as often as new objects.
TokenMacGuy
+5  A: 

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 if Foo is a reference type. The object that was referred to by object2.Foo may now be collectable if no other reference to it exists.

Henk Holterman
A: 

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.

Donnie
A: 

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).

Konamiman
+2  A: 

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.

GraemeF
Is "Fair Game" the technical term for collectible garbage? It should be!
TokenMacGuy
Correct, but "If ... object2 goes out of scope" is not in the question.
Henk Holterman
Yes, you're right. Got carried away with my ASCII art ;)
GraemeF
A: 

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.

Dean J