Вопрос (и некоторые ответы на него) смешивают две вещи: сборку мусора и финализацию.Runtime.getRuntime (). Gc () - это просто подсказка, что коллекция должна быть запущена, и очень вероятно, что диалог был собран позже (гарантии до сих пор нет).Но это не значит, что финализатор запустится.Виртуальная машина будет избегать выполнения методов финализации настолько, насколько это возможно.
Есть еще одна проблема с вашей тестовой программой.JDialog без родителя заставляет Swing создать анонимный фрейм в качестве родителя за кулисами, который останется в живых с непредсказуемыми результатами (AWT работает в другом потоке).
Попробуйте эту тестовую программу:
import java.lang.ref.WeakReference;
import javax.swing.JDialog;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) throws Throwable {
WeakReference<JDialog> ref = test();
Runtime.getRuntime().gc();
System.out.println(ref.get()==null? "collected": "still flying around");
}
public static WeakReference<JDialog> test() throws Throwable {
JDialog d = new JDialog(new JFrame());
WeakReference<JDialog> ref = new WeakReference<JDialog>(d);
d.setVisible(true);
d.dispose();
d.getOwner().dispose();
return ref;
}
}
Это работает для меня.
Альтернатива Runtime.getRuntime (). Gc ():
try {
byte[] b = new byte[Integer.MAX_VALUE];
} catch(OutOfMemoryError err) {}
, поскольку виртуальная машина гарантирует выполнение gc до OOME (может не работать с 64-битной версией).vms ;-)).