The garbage collector deals in references to objects and its analysis will locate all objects that your code maintains references to.
To answer your three questions:
- If ClassA is still referenced by your code then any objects it references (regardless of which class created them) will not be collected.
- ClassB is out of scope, meaning it is no longer referenced by your code. It is therefore eligible of collection. When this happens is not defined.
- This question is not entirely clear. The collector will collect any objects that are not referenced (directly or indirectly).
To provide a bit more background to help you understand this. When common GCs (some may not do this) start they create what is called a root set. This is a list of all the objects that are directly accessible from your code. This is created by scanning all initialised classes (for static references) as well as the registers and stack. For CMS and G1 this root set is used to perform an initial marking phase (that executes concurrently with application threads). The collector will take each object reference in the root set and traverse all object references from that to build up a complete list of objects that can be accessed from your code. If an object is unreachable it will not be marked. Once marking is complete (for CMS and G1 this requires a stop-the-world remarking phase as well) the collector has a precise list of accessible objects.
For a young gen collection, the valid objects are copied into a survivor space or promoted to the old generation. Old gen collections will either update free lists for spaces between live objects or perform a full compacting collection, relocating objects to make them all contiguous in memory, eliminating fragmentation.
There are other algorithms that do things slightly differently (like C4 from Azul, who I work for) but the overall effect is the same.