0

A code example:

public class Parent{
  public void someMethod(){
    //start of some sort of loop
    Child child = new Child(this);

    //do something
    //replaces reference from old child to new child
    child = new Child(this);
    //repeats loop
  }
}

public class Child{
   Parent parent;
   public Child(Parent parent){
     this.parent = parent;
   }
}

From what I understand of a object life cycle if a object were to be no longer referenced, then it would be eligible for gc, like when the child reference was changed to reference a new second Child object.

But what if each Child object has a reference to the object that created it, like above, would it be eligible for gc in this case once it is no longer referenced by its parent object?

If not, how can I write it so that it would be?

ivan.sim
  • 8,972
  • 8
  • 47
  • 63
Imp
  • 29
  • 4

3 Answers3

1

According to this answer:

Java's GC considers objects "garbage" if they aren't reachable through a chain starting at a garbage collection root, so these objects will be collected. Even though objects may point to each other to form a cycle, they're still garbage if they're cut off from the root.

So you don't need to do anything special for this cyclic reference case.

Community
  • 1
  • 1
Frank Kusters
  • 2,544
  • 2
  • 21
  • 30
0

If an instance of class A has a reference to an instance of class B and that instance of class B has a reference to the same instance of class A, both would not be eligible for GC as long as those references exist.

BTW, in your example, the Child instance is assigned to a local method variable inside the Parent class, so once that method is done, the Child instance would be eligible for GC, regardless of whether or not it holds a reference to the Parent instance that created it.

Now, if you'd store the Child instance reference in a member of the Parent class, you'd have a circular reference. Then, if the code that cerated the Parent instance loses all references to the Parent instance, the circular references can never be removed, so both objects won't become eligible for GC.

Consider this exmaple :

public class Parent{
    private Child child;
    public Parent {
        child = new Child(this);
    }

    public static void main (String[] args)
    {
        while (true) {
            parent = new Parent();
        }
    }
}

public class Child{
    Parent parent;
    public Child(Parent parent){
        this.parent = parent;
    }
}

Here, the main method's infinite loop would create in each iteration a new instance of Parent and Child that would never be eligible for GC, so it would eventually run out of memory.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • Oh yea i made a typo with that new Parent(), i edited. But how would i remove the reference to the Parent instance from the child class? should i make a removeParent method and inside it put parent reference to null? – Imp Sep 30 '14 at 05:16
  • In the example above, Parent has not reference to Child; the one children variable is a local variable inside the someMethod() method. – Marco Massenzio Sep 30 '14 at 05:22
  • @Nonexistent If you have a reference to the Child instance, and you have a method in the Child class that nullifies the Parent reference, you can clear that reference. But if you don't have a reference to the Child instance, you can't do it. – Eran Sep 30 '14 at 05:27
  • "If an instance of class A has a reference to an instance of class B and that instance of class B has a reference to the same instance of class A, both would not be eligible for GC as long as those references exist." That is not true. See my answer for more info. – Frank Kusters Sep 30 '14 at 06:58
  • @spaceknarf I see. I was wrong, and would delete the answer if I could. But you are also wrong in copying an answer from another question. The correct thing to do is mark this question as duplicate. – Eran Sep 30 '14 at 07:04
  • @Nonexistent Please unaccept my answer, so I can delete it. It's wrong. See correct answer in linked question. – Eran Sep 30 '14 at 07:09
0

In your someMethod(), you are creating two instances of the class Child; the fact that they both refer to the same Parent has no bearing on the fact that the first instance you created will be (eventually) GC'd once it gets de-referenced (when you re-assign the child variable, and create a new instance of a Child object).

In practice, it's not that immediate - the GC process goes through several phases (you may want to learn about Tenured, Eden and Survivor phases).

Marco Massenzio
  • 2,822
  • 1
  • 25
  • 37