在调用 JDialog.dispose 来处理 JDialog 时,我观察到 OS 和 Java 版本之间存在一些不一致的行为(也发生在 JFrame 中)。
下面的简单示例应用程序可用于演示该问题。如果您运行它并分析应用程序,您会注意到通过单击“新对话框”创建并随后关闭的任何 JDialog 实例都不会被垃圾收集,因为它们仍被 的实例引用sun.lwawt.macosx.CPlatformWindow
,从而导致应用程序中的内存泄漏。
我不相信这是由于任何弱引用,因为我在经历过的环境中观察到这个问题OutOfMemoryError
,所以我希望任何可能被垃圾收集的东西都会在那个时候出现。
问题出现在以下环境中:
- Mac OS X 10.9:Java 1.7.0_5
- Mac OS X 10.9:Java 1.7.0_45
在以下环境中不会出现此问题:
- Mac OS X 10.9:Java 1.6.0_65
- Windows 7:Java 1.7.0_45
在这些环境中,JDialog 实例被迅速收集并且(显然)不再在 JProfiler 中可见。
注意:使用 DISPOSE_ON_CLOSE 或按照示例中的注释手动处理关闭会出现问题。
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class Testing extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JDialog parent = new JDialog((Frame)null, "Parent", false);
JButton add = new JButton("New Dialog");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JDialog child = new JDialog(parent, "Child", false);
// child.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
child.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
child.setSize(100, 100);
//child.addWindowListener(new WindowAdapter() {
// @Override
// public void windowClosing(WindowEvent e) {
// child.setVisible(false);
// child.dispose();
// }
//});
child.setVisible(true);
}
});
parent.add(add);
parent.pack();
parent.setVisible(true);
}
});
}
}
有什么我做错了吗?
我的预期行为不正确吗?
如果没有,任何人都可以向我指出涵盖此问题的 Java 错误报告(我没有运气找到一个)?
任何建议的解决方法?