In Java, When Does an Object Become Unreachable

In Java, when does an object become unreachable?

When there are no longer any reference variables referring to it, OR when it is orphaned in an island.

An island being an object that has a reference variable pointing to it, however that object has no reference variables pointing to it.

class A { int i = 5; }
class B { A a = new A(); }
class C {
B b;
public static void main(String args[]) {
C c = new C();
c.b = new B();
// instance of A, B, and C created
c.b = null;
// instance of B and A eligible to be garbage collected.
}

EDIT: Just want to point out that even though the instance of A has a reference, it is on an island now because the instance of B does not have a reference to it. The A instance is eligible for garbage collection.

Java: Will an unreachable object which points to reachable object be garbage collected?

Object A is unreachable, but it has a reference which points to a valid, reachable object. So will object A be garbage collected?

Yes. (Eventually). An unreachable object is a candidate for garbage collection.

Or we are at risk of memory leak?

No.

When an object is unreachable, any references that it holds are:

  • irrelevant to the computation,
  • irrelevant to its own reachability, and
  • irrelevant to the reachability of the objects that those references refer to.

Now, it may take a long time (i.e. multiple GC runs) before your Object A is actually garbage collected. And until it is actually garbage collected, the closure of objects that it refers too won't be collected either. However, this is not a memory leak. If the JVM needs the memory, you can be assured1 that all unreachable objects are collected before the JVM throws an OOME.


1 - ... modulo certain JVM GC option settings ...

Unreachable objects on the stack cannot be garbage collected

The problem is that you still have a list iterator on the stack, and that list iterator has a reference to the original list. That's keeping the list alive just as if you'd never set objects to null.

An iterator has to keep a reference to the original collection, so that it can request the next item etc. For a regular Iterator<E> it could potentially set its internal reference to null once hasNext() had returned false, but for a list iterator even that's not the case, as you can move in both directions within a list iterator.

Is 'finalize()' method always called by garbage collector before destroying an 'Unreachable' object?

When the GC has found an object with class where finalize() has been overridden it is added to a queue of objects to have finalize() called on them. It is only after the object has been finalized once, that the GC can clean it up. i.e. this would be on a later GC.

e.g. If an object is in tenured space, it might be found until a full collection is performed, and it will only be cleaned up on a full GC after the finalize method has been called.

For further details, this is the Java 11 Javadoc for Object.finalize()

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html#finalize()

so is there any possibility that garbage collector fully destroyed the object in heap but didn't call the finalize() method on that object?

While the object is in the finalization queue, it can't be removed.

And you all assumed that there is not certainity in the destroying of object by the garbage collector.

It won't be destroyed while there is still a strong reference to it.



Related Topics



Leave a reply



Submit