为什么必须处理()超出范围的java.awt.Window?

为什么必须处理()超出范围的java.awt.Window?,java,memory-management,memory-leaks,garbage-collection,Java,Memory Management,Memory Leaks,Garbage Collection,我在应用程序中发现的内存泄漏之一是java.awt.Window.allWindowsprivate静态字段,它跟踪实例化的每个窗口。我们有创建、使用、然后遗忘的对话框,人们期望这些对话框会消失,并被垃圾收集。这个私有字段无限期地将它们保留在作用域中,直到对它们调用dispose()方法为止。根据定义,当它们超出范围时,我们不能这样做 我不明白为什么这样设计。当我处理完窗口对象时,必须明确地让系统知道这似乎与垃圾收集的精神背道而驰。显然我已经完成了,因为它超出了范围 我理解dispose()方法

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

我不明白为什么这样设计。当我处理完
窗口
对象时,必须明确地让系统知道这似乎与垃圾收集的精神背道而驰。显然我已经完成了,因为它超出了范围

我理解
dispose()
方法的作用:除去系统对等对象。我确实理解这是Java之外的,您需要某种方法来实现这一点,Swing不应该只是失去对这些对象的跟踪,否则它会有内存泄漏。但是,当我再也不打算使用它时,将对我的
窗口的引用永久保留在周围又能实现什么呢

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

这也许可以解释:

简单地说,JVM中有很多事情要做,而不仅仅是可见组件、后台线程等等。这些线程和其他资源将被维护,直到JVM上的最后一个窗口被释放,之后它们将被整理,然后JVM可以干净地退出。因此,您使用的每个窗口、框架和对话框窗口实际上都在JVM上持有一个锁,以防止JVM退出,您必须通过调用
dispose()
手动管理它


我同意这有点麻烦。我自己也曾多次与此发生冲突。

我不想这么说,但GUI就是这样工作的

窗口是非阻塞的。这意味着,一旦您在代码中创建了一个,您的代码将继续执行

这意味着您的窗口可能在创建后立即超出范围,除非您在其他地方显式存储了对它的引用。此时窗口仍在屏幕上


这也意味着当你处理完它后,你需要一些其他的方法来摆脱它。输入该方法,该方法可以从窗口的一个侦听器中调用。

在Java中,当您有本机代码(这是这些windows组件的对等程序)时,您需要保留一个引用,以防止垃圾收集器在本机指针仍然存在时尝试垃圾收集对象,这将导致各种各样的坏事情(VM崩溃等)


例如,请参阅讨论。

方法将销毁由
WindowEvent
对象持有的对象。它不会终止应用程序/程序

哦!我明白了!人们总是创建他们不保留引用的窗口,但这些窗口仍然可见并在运行。我只是没有想过,因为在这种情况下,我们会立即使用窗口,然后使其不可见,然后忘记它(超出范围)。现在我明白了为什么这是windows的默认设置。我知道某处有一个合理的用例。:)哦,对了,我应该指出,当窗口的变量超出范围时,窗口仍然在屏幕上。我会将其编辑到我的答案中,以防有人遗漏。当调用
removeNotify
时,
窗口将从
所有窗口中删除<代码>窗口
s包含本机资源,因此应以与数据库连接相同的方式进行处理。我的印象是,当数据库连接超出范围时,它们会自动关闭。我可能错了不过现在,除了短程序,所有这些都是由服务器为我管理的。