From d327c8997cbda4606dd0121539fc7c7684a69981 Mon Sep 17 00:00:00 2001 From: rstevens Date: Tue, 16 Aug 2016 19:34:31 +0300 Subject: [PATCH] 8161664: Memory leak in com.apple.laf.AquaProgressBarUI removed progress bar still referenced Reviewed-by: serb, alexsch --- .../com/apple/laf/AquaProgressBarUI.java | 8 +- .../8161664/ProgressBarMemoryLeakTest.java | 107 ++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 test/javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java diff --git a/src/macosx/classes/com/apple/laf/AquaProgressBarUI.java b/src/macosx/classes/com/apple/laf/AquaProgressBarUI.java index 1ac16c320..80a5e3682 100644 --- a/src/macosx/classes/com/apple/laf/AquaProgressBarUI.java +++ b/src/macosx/classes/com/apple/laf/AquaProgressBarUI.java @@ -124,7 +124,9 @@ public class AquaProgressBarUI extends ProgressBarUI implements ChangeListener, if (!progressBar.isIndeterminate()) return; stopAnimationTimer(); // start the animation thread - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } if ("JProgressBar.style".equals(prop)) { @@ -141,7 +143,9 @@ public class AquaProgressBarUI extends ProgressBarUI implements ChangeListener, public void ancestorAdded(final AncestorEvent e) { if (!progressBar.isIndeterminate()) return; - startAnimationTimer(); + if (progressBar.isDisplayable()) { + startAnimationTimer(); + } } public void ancestorMoved(final AncestorEvent e) { } diff --git a/test/javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java b/test/javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java new file mode 100644 index 000000000..852aacb0c --- /dev/null +++ b/test/javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, 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 8161664 + * @summary Memory leak in com.apple.laf.AquaProgressBarUI: removed progress bar still referenced + * @library ../../regtesthelpers + * @build Util + * @run main/timeout=300/othervm -Xmx16m ProgressBarMemoryLeakTest + */ +import java.awt.EventQueue; +import java.lang.ref.WeakReference; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class ProgressBarMemoryLeakTest { + + private static JFrame sFrame; + private static WeakReference sProgressBar; + + public static void main(String[] args) throws Exception { + UIManager.LookAndFeelInfo[] installedLookAndFeels = UIManager.getInstalledLookAndFeels(); + for ( UIManager.LookAndFeelInfo installedLookAndFeel : installedLookAndFeels ) { + executeTestCase(installedLookAndFeel.getClassName()); + } + } + + private static void executeTestCase(String lookAndFeelString) throws Exception{ + if (tryLookAndFeel(lookAndFeelString)) { + EventQueue.invokeAndWait( new Runnable() { + @Override + public void run() { + showUI(); + } + } ); + EventQueue.invokeAndWait( new Runnable() { + @Override + public void run() { + disposeUI(); + } + } ); + Util.generateOOME(); + JProgressBar progressBar = sProgressBar.get(); + if ( progressBar != null ) { + throw new RuntimeException( "Progress bar (using L&F: " + lookAndFeelString + ") should have been GC-ed" ); + } + } + } + + private static void showUI(){ + sFrame = new JFrame(); + + JProgressBar progressBar = new JProgressBar(); + progressBar.setVisible(false); + progressBar.setIndeterminate(false); + progressBar.setIndeterminate(true); + progressBar.setIndeterminate(false); + progressBar.setValue(10); + progressBar.setString("Progress"); + + sFrame.add(progressBar); + + sProgressBar = new WeakReference<>(progressBar); + + sFrame.setSize(200,200); + sFrame.setVisible(true); + } + + private static void disposeUI(){ + sFrame.setContentPane(new JPanel()); + sFrame.dispose(); + sFrame = null; + } + + private static boolean tryLookAndFeel(String lookAndFeelString) throws Exception { + try { + UIManager.setLookAndFeel(lookAndFeelString); + } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { + return false; + } + return true; + } +} -- GitLab