我在应用程序中发现的一个内存泄漏是java.awt.Window.allWindows
私有静态字段,它跟踪实例化的每个Window
。我们创建,使用,然后忘记了对话框,期望这些对话框会消失并被垃圾收集。此私有字段会无限期地将它们保留在范围内,直到调用dispose()
方法为止。根据定义,当它们超出范围时,我们不能这样做。
我不明白为什么这是这样设计的。当我完成Window
对象时,必须明确让系统知道,这与垃圾收集的精神相反。显然我已经完成了它,因为它超出了范围。
我理解dispose()
方法正在做什么:摆脱系统对等体。我确实理解这是在Java之外,你需要一些方法来做到这一点,并且Swing不应该只是失去对这些对象的跟踪,否则它会有内存泄漏。但是,当我永远不再使用它时,通过永久保持对Window
的引用来实现什么呢?
有人可以解释为什么这是必要的吗?
答案 0 :(得分:14)
我不想这么说,但这就是GUI的运作方式。
Windows是非阻止的。这意味着一旦在代码中创建了一个代码,代码就会继续执行。
这意味着您的Window可能会在创建后立即超出范围,除非您在其他位置明确存储了对它的引用。此时窗口仍在屏幕上。
这也意味着当你完成它之后你需要一些其他方法来摆脱它。输入Window dispose()
方法,可以从其中一个Window的侦听器中调用。
答案 1 :(得分:2)
这可以解释一下:AWT Threading Issues
简单地说,JVM中的内容远远多于可见组件,后台线程等等。维护这些线程和其他资源,直到JVM上的最后一个窗口被放置,然后它们被整理,然后JVM可以干净地退出。因此,您使用的每个窗口,框架和对话框窗口实际上都是锁定JVM以防止它退出,您必须通过调用dispose()
来手动管理它。
我同意这有点像虫子。我自己也曾多次与此发生过冲突。
答案 2 :(得分:1)
在Java中,当你有本机代码(这些是这些windows组件的同行)时,你需要保留一个引用来防止垃圾收集器在本机指针仍然存在时尝试垃圾收集对象,会导致各种不好的事情(VM崩溃等)。
例如,请参阅讨论here。
答案 3 :(得分:1)
dispose()
方法会销毁WindowEvent
对象持有的对象。它不会杀死应用程序/程序。