java - JDialog 永远不会被垃圾回收

标签 java swing garbage-collection jdialog

为什么下面的代码从不对 JDialog 实例进行垃圾回收? 实例 X 没有引用,对话框已被释放。

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();
    }

}

}

谢谢

最佳答案

问题是(有些答案是)混合垃圾收集和终结这两种东西。 Runtime.getRuntime().gc() 只是提示收集应该运行,很可能之后收集了对话框(仍然没有保证)。但这并不意味着终结器会运行。虚拟机将尽可能避免运行 finalize 方法。

您的测试程序还有另一个问题。没有父级的 JDialog 强制 Swing 在幕后创建一个匿名 Frame 作为父级,它将保持 Activity 状态并产生不可预测的结果(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) {}

因为虚拟机保证在 OOME 之前执行 gc(可能不适用于 64 位虚拟机 ;-))。

关于java - JDialog 永远不会被垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5883347/

相关文章:

Java 桌面应用程序(awt/swing GUI)到 Web 应用程序

android - GC 运行过于频繁

java - 读取 ClassLoader.getSystemResourceAsStream 后是否需要显式关闭输入流?

java - Jersey 客户端收到错误的响应

java - 使用RxJava观察List "add"和 "remove" Action

java - 如何在 Java 中堆叠/覆盖 jPanel?

java - 如何从来自 MQ 的消息中检索 RFH 消息头?

java - 在 JGoodies WindowsLookAndFeel 中更改 JButton 的颜色

java - G1 垃圾收集器 : Why survivor space is always full?

java - 对象变为空