OpenJDK / jdk / jdk
changeset 8757:2afba8862932
6464022: Memory leak in JOptionPane.createDialog
Reviewed-by: alexp
author | rupashka |
---|---|
date | Mon, 14 Mar 2011 15:01:53 +0300 |
parents | 6b492caeba16 |
children | edb1ed26dd1b |
files | jdk/src/share/classes/javax/swing/JOptionPane.java jdk/test/javax/swing/JOptionPane/6464022/bug6464022.java jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java jdk/test/javax/swing/regtesthelpers/Util.java |
diffstat | 4 files changed, 154 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/javax/swing/JOptionPane.java Sat Mar 05 20:54:53 2011 -0800 +++ b/jdk/src/share/classes/javax/swing/JOptionPane.java Mon Mar 14 15:01:53 2011 +0300 @@ -987,11 +987,33 @@ } dialog.pack(); dialog.setLocationRelativeTo(parentComponent); + + final PropertyChangeListener listener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + // Let the defaultCloseOperation handle the closing + // if the user closed the window without selecting a button + // (newValue = null in that case). Otherwise, close the dialog. + if (dialog.isVisible() && event.getSource() == JOptionPane.this && + (event.getPropertyName().equals(VALUE_PROPERTY) || + event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) && + event.getNewValue() != null && + event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) { + dialog.setVisible(false); + } + } + }; + WindowAdapter adapter = new WindowAdapter() { private boolean gotFocus = false; public void windowClosing(WindowEvent we) { setValue(null); } + + public void windowClosed(WindowEvent e) { + removePropertyChangeListener(listener); + dialog.getContentPane().removeAll(); + } + public void windowGainedFocus(WindowEvent we) { // Once window gets focus, set initial focus if (!gotFocus) { @@ -1008,20 +1030,8 @@ setValue(JOptionPane.UNINITIALIZED_VALUE); } }); - addPropertyChangeListener(new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - // Let the defaultCloseOperation handle the closing - // if the user closed the window without selecting a button - // (newValue = null in that case). Otherwise, close the dialog. - if (dialog.isVisible() && event.getSource() == JOptionPane.this && - (event.getPropertyName().equals(VALUE_PROPERTY) || - event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) && - event.getNewValue() != null && - event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) { - dialog.setVisible(false); - } - } - }); + + addPropertyChangeListener(listener); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JOptionPane/6464022/bug6464022.java Mon Mar 14 15:01:53 2011 +0300 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6464022 + * @summary Memory leak in JOptionPane.createDialog + * @author Pavel Porvatov + * @library ../../regtesthelpers + * @build Util + * @run main bug6464022 + */ + +import javax.swing.*; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +public class bug6464022 { + private static JOptionPane pane; + + public static void main(String[] args) throws Exception { + final List<WeakReference<JDialog>> references = new ArrayList<WeakReference<JDialog>>(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + pane = new JOptionPane(null, JOptionPane.UNDEFINED_CONDITION); + + for (int i = 0; i < 10; i++) { + JDialog dialog = pane.createDialog(null, "Test " + i); + + references.add(new WeakReference<JDialog>(dialog)); + + dialog.dispose(); + + System.out.println("Disposing Dialog:" + dialog.hashCode()); + } + } + }); + + Util.generateOOME(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + int allocatedCount = 0; + + for (WeakReference<JDialog> ref : references) { + if (ref.get() != null) { + allocatedCount++; + + System.out.println(ref.get().hashCode() + " is still allocated"); + } + } + + if (allocatedCount > 0) { + throw new RuntimeException("Some dialogs still exist in memory. Test failed"); + } else { + System.out.println("All dialogs were GCed. Test passed."); + } + } + }); + } +}
--- a/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java Sat Mar 05 20:54:53 2011 -0800 +++ b/jdk/test/javax/swing/UIDefaults/6795356/bug6795356.java Mon Mar 14 15:01:53 2011 +0300 @@ -26,6 +26,8 @@ * @bug 6795356 * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc * @author Alexander Potochkin + * @library ../../regtesthelpers + * @build Util * @run main bug6795356 */ @@ -58,43 +60,11 @@ weakRef = new WeakReference<ProtectionDomain>(domain); domain = null; - // Generate OutOfMemory and check the weak ref - generateOOME(); + Util.generateOOME(); if (weakRef.get() != null) { throw new RuntimeException("Memory leak found!"); } System.out.println("Test passed"); } - - static void generateOOME() { - List<Object> bigLeak = new LinkedList<Object>(); - boolean oome = false; - System.out.print("Filling the heap"); - try { - for(int i = 0; true ; i++) { - // Now, use up all RAM - bigLeak.add(new byte[1024 * 1024]); - System.out.print("."); - - // Give the GC a change at that weakref - if (i % 10 == 0) { - System.gc(); - try { - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } catch (OutOfMemoryError e) { - bigLeak = null; - oome = true; - } - System.out.println(""); - if (!oome) { - throw new RuntimeException("Problem with test case - never got OOME"); - } - System.out.println("Got OOME"); - } }
--- a/jdk/test/javax/swing/regtesthelpers/Util.java Sat Mar 05 20:54:53 2011 -0800 +++ b/jdk/test/javax/swing/regtesthelpers/Util.java Mon Mar 14 15:01:53 2011 +0300 @@ -24,6 +24,8 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.util.LinkedList; +import java.util.List; /** * <p>This class contains utilities useful for regression testing. @@ -72,4 +74,46 @@ return true; } + + /** + * Fills the heap until OutOfMemoryError occurs. This method is useful for + * WeakReferences removing. + */ + public static void generateOOME() { + List<Object> bigLeak = new LinkedList<Object>(); + + boolean oome = false; + + System.out.print("Filling the heap"); + + try { + for(int i = 0; true ; i++) { + // Now, use up all RAM + bigLeak.add(new byte[1024 * 1024]); + + System.out.print("."); + + // Give the GC a change at that weakref + if (i % 10 == 0) { + System.gc(); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } catch (OutOfMemoryError e) { + bigLeak = null; + oome = true; + } + + System.out.println(""); + + if (!oome) { + throw new RuntimeException("Problem with test case - never got OOME"); + } + + System.out.println("Got OOME"); + } }