6
votes

Lets say I have 2 objects - object A and object B. Object A references Object B and object B references Object A.

  1. If Both Object A & Object B are out of ref of the code - how does Garbage collector know that it can be collected.
  2. How does Garbage collector deduce that any object is out of scope / ready for garbage collection?
  3. What about if Object A is not ref by our code but can still be independent. E.g. if it is a Form class then it can run on its own even if Object A is reinitialized to a new instance or specified null.
2
You should read this: msdn.microsoft.com/en-us/library/ee787088.aspx It answers your questions and more. (Roughly: the GC has a list of things it knows are alive (static references, stack variables, etc.) which are "roots". Any other object that can be reached by traversing references starting at those roots is also considered alive. Any object which can't is considered eligible for collection.)dlev
I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not".John Saunders
If you're interested in this kind of stuff, the absolute best book (IMO) is CLR Via C# (which is in its 4th edition and has a newly updated section about the garbage collector). I can't recommend it highly enough. It really does a great job of explaining just what's going on in the CLR.Matthew Watson

2 Answers

6
votes
  1. The GC doesn't pick an object and look to see if anything references it; keeping it if it does. The GC has a collection of every object that it knows is "alive". This collection starts out as all static variables, all variables on the stack, and a few other special cases. It then goes through each of those "alive" objects and sees what objects they reference. Each referenced object is itself marked as "alive" since it means that it is somehow reachable by another alive object. It repeats this process until no new objects are discovered. Anything that wasn't marked as alive is then known to be unreachable. As you can tell, since you have never inspected what any given "dead" object references, whether or not there is a circular reference isn't relevant.

  2. See #1.

  3. Well, in most of these cases it is actually referenced somewhere; in the case of a form, for example, you have Application.OpenForms referencing any open forms. Similar constructs often exist for objects such as these. In rare cases with objects such as timers they are explicitly told by the GC to not be collected. Such situations are very rare and you generally don't need to worry about them.

0
votes
  1. The garbage collector looks through the active references, and anything that isn't found from there can be collected. That way it doesn't matter that the two objects reference each other, because both those references are inactive.

  2. See 1.

  3. A form is a component, so it's kept alive by being registered as one. Once initialised the application itself keeps it alive, until the form is disposed. Having a variable that references the form and then setting the variable to null only changes the reference, it doesn't do anything to the object itself.