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();
}
}
}
谢谢
Why does the following code never garbage collect the JDialog instance ?
The instance X has no reference and the dialog has been disposed.
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();
}
}
}
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
问题是(一些答案是)混合了垃圾收集和终结这两种东西。 Runtime.getRuntime().gc() 只是一个提示,表明该收集应该运行,并且很可能该 Dialog 之后已被收集(仍然没有保证)。但这并不意味着终结器将会运行。虚拟机将尽可能避免运行 Finalize 方法。
您的测试程序还有另一个问题。没有父级的 JDialog 会强制 Swing 在幕后创建一个匿名 Frame 作为父级,这将保持活动状态并产生不可预测的结果(AWT 在不同的线程中运行)。
试试这个测试程序:
这对我有用。
Runtime.getRuntime().gc() 的替代方法是:
因为 vm 保证在 OOME 之前执行 gc(可能不适用于 64 位 vm;-))。
The question is (and some of the answers are) mixing two things, garbage collection and finalization. Runtime.getRuntime().gc() is just a hint that the collection should run and it’s very likely that the Dialog has been collected afterward (there’s still no guaranty). But this does not mean that the finalizer will run. The virtual machine will avoid running finalize methods as much as it can.
There is another issue with your test program. JDialog without a parent forces Swing to create an anonymous Frame as parent behind the scenes which will stay alive with unpredictable results (AWT runs within a different thread).
Try this test program:
This works for me.
An alternative to Runtime.getRuntime().gc() is:
as the vm guarantees performing gc before OOME (might not work with 64bit vms ;-) ).
无法预期 GC 调用会在特定时间发生。它是随机调用的,或者当 JVM 分配的内存已满时调用。
PS 您的
x.dispose();
不调用 GC。它可能只是标记这个对象可以被收集。The GC calls can't be expected at the specific time. It is called randomly or when there is full memory allocated by the JVM.
P.S. Your
x.dispose();
don't call the GC. It may just mark that this object can be collected.正如之前所说 - 你不能指望在特定时间进行 GC。但你可以通过填充内存来“强制”它。
尝试这个代码,它在处理你的类后填充内存。它在循环中分配很多 Long,但任何更大的类都会更好。 (认为这足以满足我的默认值)
As was said before - you cannot expect GC at the specific time. But you can "force" it by filling up the memory.
try this code, it fills memory after disposing your class. It allocates a lot of Longs in loop but any bigger class would be better. (thought thi suffice on my defaults)
对话框中的第一个永远不会被 GC 处理,并且存在一些错误,但是不幸的是***,bugsParade 现在被冻结了
dispose() 与 GC 无关 http://download.oracle.com/javase/6/docs/api/java/awt/Window.html#dispose%28%29
dialog the first one is never GC'ed, and there are some bugs with that, but unfor***, bugsParade is freeze now
dispose() has nothing to do with GC http://download.oracle.com/javase/6/docs/api/java/awt/Window.html#dispose%28%29
JVM 在需要运行垃圾收集之前停止。因此,
JDialog
永远不会被垃圾回收,因此永远不会最终确定。The JVM stops before the garbage collection needs to be run. Therefore the
JDialog
is never garbage collected and thus never finalized.