1

Assume Outer is instantiated somewhere, and after a while there are no references to it. Does the implicit reference in inner to the Outer instance prevent GC from running, or does the is it a "special" reference?

public class Outer {
    private class Inner extends Something {}

    private Inner inner = new Inner();
}
Eliezer
  • 7,209
  • 12
  • 56
  • 103
  • 1
    If an object tree is not reached form GC root it will be the subject of GC. In your sample it is. http://stackoverflow.com/questions/6366211/what-are-the-roots/28057186#28057186 – vrudkovsk Apr 13 '15 at 05:46

1 Answers1

3

If the instance of Outer is not reachable from a GC root, the reference to an Inner instance in your example code will not stop the garbage collector from freeing the memory the Outer used.

Consider this diagram:

Stack of main thread           public static void main(String[] args) {
         |                       Outer outer = new Outer();
         v                     
       Outer<--\
         |\    |
         v \---/
       Inner 

Stack of main thread               outer = new Outer();
         |
         v          
       Outer<--\
         |\ new|
         v \---/
       Inner 

       Outer<--\                   // a reference to the Outer from the Inner
         |\ old|                   // doesn't change the fact that the Outer
         v \---/                   // can't be reached from a GC root.
       Inner                       // Thus the old Outer is eligible for collection (dead)
jdphenix
  • 15,022
  • 3
  • 41
  • 74
  • Just to clarify, since there are no references to `Outer` besides for one from "inside" itself, it is eligible for GC? – Eliezer Apr 13 '15 at 05:48
  • 1
    Not quite, it is eligible for GC under the assertion you made in your question *"and after a while there are no references to it [`Outer`]"* – jdphenix Apr 13 '15 at 05:50
  • Yes, that's what I meant. I should have been more explicit. – Eliezer Apr 13 '15 at 05:58