我在调用JDialog.dispose来处置JDialog(也出现在JFrame中)时观察到OS和Java版本之间的某些不一致的行为。Mac OS Java 7 JDialog.dispose内存泄漏
下面的简单示例应用程序可用于演示此问题。如果运行它并对应用程序进行配置,您将注意到,通过单击“New Dialog”创建并随后关闭的任何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报告,涵盖了这个(我没有找到幸运的运气)?
任何建议的解决方法?
检查一个相关示例[here](http://stackoverflow.com/a/6310284/230513)。 – trashgod
@trashgod谢谢,我在调查过程中看到了这一点。然而,我没有看到它是如何直接在这里应用的,因为在以前的Java版本和不同的操作系统中,我看到不同的行为给予完全相同的代码。 –
可能是延迟或错误,但也请参阅[答案](http://stackoverflow.com/a/2486200/230513)。 – trashgod