为什么你必须 dispose() 一个超出范围的 java.awt.Window ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1407161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why should you have to dispose() a java.awt.Window that goes out of scope?
提问by skiphoppy
One of the memory leaks I've discovered in our application is the java.awt.Window.allWindowsprivate static field, which keeps track of every Windowinstantiated. We have dialog boxes that are created, used, and then forgotten, and the expectation was that these would go away and be garbage collected. This private field keeps them in scope, indefinitely, until the dispose()method is called on them. And by definition, we can't do that when they've gone out of scope.
我在我们的应用程序中发现的内存泄漏之一是java.awt.Window.allWindows私有静态字段,它跟踪每个Window实例化。我们有创建、使用、然后被遗忘的对话框,期望它们会消失并被垃圾收集。这个私有字段将它们无限期地保留在范围内,直到dispose()对它们调用方法为止。根据定义,当它们超出范围时,我们不能这样做。
I don't understand why this is designed this way. It seems contrary to the spirit of garbage collection to have to explicitly let the system know when I'm done with a Windowobject. Obviously I'm done with it, as it is out of scope.
我不明白为什么要这样设计。当我处理完一个Window对象时,必须明确地让系统知道这似乎有悖于垃圾收集的精神。显然我已经完成了,因为它超出了范围。
I understand what the dispose()method is doing: getting rid of system peer objects. I do understand that this is outside of Java and that you need some way to do that and that Swing shouldn't just lose track of those objects, or else it would have a memory leak. But what is accomplished by keeping a reference to my Windowaround forever, when I am never going to use it again?
我了解该dispose()方法在做什么:摆脱系统对等对象。我确实理解这是在 Java 之外,您需要某种方法来做到这一点,并且 Swing 不应该只是丢失对这些对象的跟踪,否则它会发生内存泄漏。但是Window当我永远不会再使用它时,通过永远保持对我周围的引用来完成什么?
Can someone explain why this is necessary?
有人可以解释为什么这是必要的吗?
回答by Powerlord
I hate to say it, but that's just how a GUI works.
我不想这么说,但这就是 GUI 的工作方式。
Windows are non-blocking. Meaning that once you create one in code, your code continues to execute.
Windows 是非阻塞的。这意味着一旦你在代码中创建了一个,你的代码就会继续执行。
This means that your Window probably goes out of scope immediately after creation, unless you explicitly stored a reference to it somewhere else. The Window is still on screen at this point.
这意味着您的 Window 可能会在创建后立即超出范围,除非您在其他地方显式存储对它的引用。此时窗口仍在屏幕上。
This also means you need some other way to get rid of it when you're done with it. Enter the Window dispose()method, which can be called from within one of the Window's listeners.
这也意味着当你完成它时,你需要一些其他的方法来摆脱它。输入Window dispose()可以从 Window 的侦听器之一中调用的方法。
回答by banjollity
This might explain it: AWT Threading Issues
这可能会解释它:AWT 线程问题
Simply, there's a lot more going on in the JVM than just the visible components, with background threads and so on. These threads and other resources are maintained until the last window on the JVM has been disposed, after which they are tidied up, and the JVM can then exit cleanly. So every window, frame and dialog window that you use is essentially holding a lock on the JVM to prevent it from quitting, and you have to manually manage this with calls to dispose().
简单地说,JVM 中发生的事情不仅仅是可见的组件,还有后台线程等等。这些线程和其他资源会一直保持到 JVM 上的最后一个窗口被处理完毕,然后将它们整理好,然后 JVM 就可以干净地退出了。因此,您使用的每个窗口、框架和对话窗口本质上都在 JVM 上持有锁以防止其退出,您必须通过调用dispose().
I agree it's a bit of a bugger. I've run afoul of this a few times myself.
我同意这有点麻烦。我自己也遇到过几次这种情况。
回答by Yishai
In Java when you have native code (which is what the peers of these windows components are), you need to keep a reference to prevent the garbage collector from trying to garbage collect the object while the native pointers are still around, which would cause all kinds of bad stuff (VM crashes, etc.).
在 Java 中,当您拥有本机代码(这就是这些 windows 组件的对等点)时,您需要保留一个引用,以防止垃圾收集器在本机指针还在时尝试对对象进行垃圾收集,这将导致所有各种各样的坏事(VM 崩溃等)。
See, for example, the discussion here.
例如,请参阅此处的讨论。
回答by satya
The dispose()method destroys the object held by the WindowEventobject. It does not kill the application/program.
该dispose()方法销毁对象持有的WindowEvent对象。它不会终止应用程序/程序。

