6919629: Nimbus L&F Nimbus.Overrides option leaks significant amounts of memory
authorpeterz
Thu, 06 May 2010 12:57:30 +0400
changeset 5453 3d39f942ca6e
parent 5452 6645e1f6569d
child 5454 37dd87f1b78f
child 5581 9c2282c6f080
6919629: Nimbus L&F Nimbus.Overrides option leaks significant amounts of memory Reviewed-by: rupashka
jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java
jdk/test/javax/swing/plaf/nimbus/Test6919629.java
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Fri Apr 30 11:03:38 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Thu May 06 12:57:30 2010 +0400
@@ -38,6 +38,7 @@
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Insets;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -193,7 +194,7 @@
      * UIDefaults which overrides (or supplements) those defaults found in
      * UIManager.
      */
-    private JComponent component;
+    private WeakReference<JComponent> component;
 
     /**
      * Create a new NimbusStyle. Only the prefix must be supplied. At the
@@ -209,7 +210,9 @@
      *        should be null otherwise.
      */
     NimbusStyle(String prefix, JComponent c) {
-        this.component = c;
+        if (c != null) {
+            this.component = new WeakReference<JComponent>(c);
+        }
         this.prefix = prefix;
         this.painter = new SynthPainterImpl(this);
     }
@@ -251,9 +254,11 @@
         // value is an instance of UIDefaults, then these defaults are used
         // in place of, or in addition to, the defaults in UIManager.
         if (component != null) {
-            Object o = component.getClientProperty("Nimbus.Overrides");
+            // We know component.get() is non-null here, as if the component
+            // were GC'ed, we wouldn't be processing its style.
+            Object o = component.get().getClientProperty("Nimbus.Overrides");
             if (o instanceof UIDefaults) {
-                Object i = component.getClientProperty(
+                Object i = component.get().getClientProperty(
                         "Nimbus.Overrides.InheritDefaults");
                 boolean inherit = i instanceof Boolean ? (Boolean)i : true;
                 UIDefaults d = (UIDefaults)o;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/nimbus/Test6919629.java	Thu May 06 12:57:30 2010 +0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @bug 6919629
+   @summary Tests that components with Nimbus.Overrides are GC'ed properly
+   @author Peter Zhelezniakov
+   @run main Test6919629
+*/
+
+import java.awt.Color;
+import java.lang.ref.WeakReference;
+import javax.swing.*;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+public class Test6919629
+{
+    JFrame f;
+    WeakReference<JLabel> ref;
+
+    public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel(new NimbusLookAndFeel());
+        Test6919629 t = new Test6919629();
+        t.test();
+        System.gc();
+        t.check();
+    }
+
+    void test() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                UIDefaults d = new UIDefaults();
+                d.put("Label.textForeground", Color.MAGENTA);
+
+                JLabel l = new JLabel();
+                ref = new WeakReference<JLabel>(l);
+                l.putClientProperty("Nimbus.Overrides", d);
+
+                f = new JFrame();
+                f.getContentPane().add(l);
+                f.pack();
+                f.setVisible(true);
+            }
+        });
+        Thread.sleep(2000);
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                f.getContentPane().removeAll();
+                f.setVisible(false);
+                f.dispose();
+            }
+        });
+        Thread.sleep(2000);
+    }
+
+    void check() {
+        if (ref.get() != null) {
+            throw new RuntimeException("Failed: an unused component wasn't collected");
+        }
+    }
+}