我在調用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