0

Will instances of class A be garbage-collected or will they remain in memory forever?

I know that if an object becomes eligible for Garbage Collection and its finalize() method has been called and inside this method the object becomes accessible by a live thread of execution, it is not garbage collected.

public class A{

  String someString = null;
  private A a=null;
  public String getSomeString() {
    return someString;
  }
  public void setSomeString(String someString) {
    this.someString = someString;
  }
  @Override
  protected void finalize() throws Throwable {
    try {
      this.a=this;
      System.out.println("final called");      
    } finally {
      super.finalize();
    }
  }
}
public static void main(String args[]) throws Exception {
  A s1=new A();
  s1=null;
  System.gc();
  System.out.println("gc called");
  ......
}

Inspired by Can we switch off finalizers?

Community
  • 1
  • 1
Darshan Patel
  • 3,176
  • 6
  • 26
  • 49
  • this.a=this wont prevent gc, there are still no reference to this object by something 'life' and therefore it will be gc. If you would reference it from something else (like a live thread) then it would likely to survive. – MoonBun Jan 06 '14 at 14:30
  • @Vladp Make that an answer and you'll get my up-vote... – Duncan Jones Jan 06 '14 at 14:32
  • @Vladp i think this.a=this assigns reference to it's property? correct me if i am wrong.. – Darshan Patel Jan 06 '14 at 14:34

2 Answers2

4

That assignment (in the finalize()) method doesn't make the target object (this) strongly reachable, so it won't prevent it from being garbage collected.

On the other hand, if you did this:

    otherObject.a = this;

and otherObject referred to a strongly reachable object, then the assignment would make this strongly reachable, and it would prevent the object from being collected (while it remained reachable ...). But next time this became unreachable, the finalize method would NOT be called. An object's finalize method is only ever called once in the object's lifetime.


i think this.a=this assigns reference to it's property? correct me if i am wrong..

You are correct, but it makes no difference. All you are doing is making this point to itself. That doesn't make it reachable ...

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • So there is a way to actually make a memory leak in java? nice. – MoonBun Jan 06 '14 at 14:46
  • @Vladp - Not in the sense that you mean, I think. – Stephen C Jan 06 '14 at 14:56
  • If you call finalize on purpose (and use otherObject.a = this) and then make it unreachable again, the gc wont collect it and it will create a memory leak. wrong? – MoonBun Jan 06 '14 at 15:07
  • @Vladp: you are mixing up things. If you “call finalize on purpose”, it has no effect, the JVM doesn’t care. If *the JVM invoked finalize()*, it won’t do that again on the same object, but that doesn’t prevent *collection* of the object, the object’s memory will just be released without the invocation of `finalize()`. – Holger Apr 26 '16 at 19:03
2

The line you added

this.a=this;

is not something that will prevent A from being GC, this object is still not being referenced from something valid like a live thread.

Try looking at a more complex structure: List

if you point the last node to the first (circular list), and then to set your Node head = null; then maybe each node is still being pointed from the other node but the whole List is not being referenced from a live thread and there for will be garbage collected.

Garbage collector is not just checking if the object is being referenced, but deep checking if there is a reference from a valid thread.

Bottom line is:

If an object is unreachable from a thread it's garbage collected. In your case A is not reachable any more.

MoonBun
  • 4,322
  • 3
  • 37
  • 69