为什么要处理超出范围的java.awt.Window?

我在我们的应用程序中发现的一个内存泄漏是java.awt.Window.allWindows私有静态字段,它跟踪实例化的每个Window 。 我们创建,使用,然后忘记了对话框,期望这些对话框会消失并被垃圾收集。 这个私有字段无限期地将它们保留在范围内,直到在它们上调用dispose()方法。 根据定义,当他们超出范围时,我们不能这样做。

我不明白为什么这是这样设计的。 与垃圾收集的精神相反,当我完成Window对象时,必须明确地让系统知道。 显然我已经完成了它,因为它超出了范围。

我理解dispose()方法正在做什么:摆脱系统对等对象。 我确实理解这是在Java之外,你需要一些方法来做到这一点,并且Swing不应该只是失去对这些对象的跟踪,否则它会有内存泄漏。 但是,当我永远不再使用它时,通过永久保持对我的Window的引用来实现什么?

有人可以解释为什么这是必要的吗?

我不想这么说,但这就是GUI的工作原理。

Windows是非阻塞的。 这意味着一旦在代码中创建一个代码,代码就会继续执行。

这意味着您的Window可能会在创建后立即超出范围,除非您在其他位置明确存储了对它的引用。 此时窗口仍在屏幕上。

这也意味着当你完成它时,你需要一些其他方法来摆脱它。 输入Window dispose()方法,该方法可以从一个Window的侦听器中调用。

这可以解释一下: AWT线程问题

简单地说,JVM中的内容远远多于可见组件,后台线程等等。 维护这些线程和其他资源,直到JVM上的最后一个窗口被处理完毕,然后它们被整理,然后JVM可以干净地退出。 因此,您使用的每个窗口,框架和对话框窗口实际上都是锁定JVM以防止它退出,您必须通过调用dispose()手动管理它。

我同意这是一个bugger。 我自己已经和我发生了几次冲突。

在Java中,当你有本机代码(这些是这些windows组件的对等端)时,你需要保留一个引用来防止垃圾收集器在本机指针仍然存在时尝试垃圾收集对象,这将导致所有各种不好的东西(VM崩溃等)。

例如,请参见此处的讨论。

dispose()方法销毁WindowEvent对象持有的对象。 它不会杀死应用程序/程序。