Why does the following code never garbage collect the JDialog instance ?
The instance X has no reference and the dialog has been disposed.
public class Test {
public static void main(String[] args) throws Throwable {
test();
Runtime.getRuntime().gc();
}
public static void test() throws Throwable {
X x = new X();
x.setVisible(true);
x.dispose();
}
public static class X extends JDialog {
public X() {
super();
}
@Override
protected void finalize() throws Throwable {
System.out.println("destroyed !");
super.finalize();
}
}
}
Thank you
The question is (and some of the answers are) mixing two things, garbage collection and finalization. Runtime.getRuntime().gc() is just a hint that the collection should run and it’s very likely that the Dialog has been collected afterward (there’s still no guaranty). But this does not mean that the finalizer will run. The virtual machine will avoid running finalize methods as much as it can.
There is another issue with your test program. JDialog without a parent forces Swing to create an anonymous Frame as parent behind the scenes which will stay alive with unpredictable results (AWT runs within a different thread).
Try this test program:
This works for me.
An alternative to Runtime.getRuntime().gc() is:
as the vm guarantees performing gc before OOME (might not work with 64bit vms 😉 ).