I had an interview today, and the interviewer presented the following code. They asked what the output would be in Java 8 and the latest version of Java.
From my understanding, since B
is an inner class (non-static nested class), it holds a reference to the instance of A
, which prevents A
from being garbage collected (GC). This behavior is expected in Java 8. However, the interviewer demonstrated that A
can be garbage collected in the latest version of Java (Java 23). He then asked in which version of Java this change occurred and why A
can now be GC'd. I believe this behavior is either related to the new mechanism of inner classes (a
is GC'd even when b
is still alive. In principle, b
should hold reference to a
) or the new garbage collection process. However, I don't know the answer.
class A {
class B {
@Override
protected void finalize() throws Throwable {
System.out.println("B destroy");
}
}
@Override
protected void finalize() throws Throwable {
System.out.println("A destroy");
}
}
public class Solution {
public static void main(String[] args) throws InterruptedException {
A a = new A();
A.B b = a.new B();
a = null;
System.gc();
System.out.println("finish gc");
Thread.sleep(1000);
System.out.println("finish sleep");
}
}
Output of Java 8
finish gc
finish sleep
Output of Java 23
finish gc
A destroy
finish sleep
By experimenting with each version of Java from 23 downwards, I discovered that this phenomenon started in Java 18. I then looked up the new features of Java 18.
Enclosing Instance Fields Omitted from Inner Classes That Don't Use Them https://www.oracle.com/java/technologies/javase/18-relnote-issues.html#JDK-8271623
Prior to JDK 18, when javac compiles an inner class it always generates a private synthetic field with a name starting with this$ to hold a reference to the enclosing instance, even if the inner class does not reference its enclosing instance and the field is unused. Starting in JDK 18, unused this$ fields are omitted; the field is only generated for inner classes that reference their enclosing instance.