7019441: No lookup cache for internal composite font creation leads to java heap growth
authorprr
Wed, 16 Feb 2011 15:58:28 -0800
changeset 8357 7da1b1af2da0
parent 8356 64c792dbf671
child 8358 39c22ace748d
7019441: No lookup cache for internal composite font creation leads to java heap growth Reviewed-by: igor, jgodinez
jdk/src/share/classes/sun/font/FontUtilities.java
--- a/jdk/src/share/classes/sun/font/FontUtilities.java	Fri Feb 11 10:40:24 2011 -0800
+++ b/jdk/src/share/classes/sun/font/FontUtilities.java	Wed Feb 16 15:58:28 2011 -0800
@@ -30,6 +30,8 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
+import java.lang.ref.SoftReference;
+import java.util.concurrent.ConcurrentHashMap;
 import java.security.AccessController;
 
 import java.security.PrivilegedAction;
@@ -383,6 +385,10 @@
      * }
      * return fuir;
      */
+    private static volatile
+        SoftReference<ConcurrentHashMap<PhysicalFont, CompositeFont>>
+        compMapRef = new SoftReference(null);
+
     public static FontUIResource getCompositeFontUIResource(Font font) {
 
         FontUIResource fuir = new FontUIResource(font);
@@ -402,12 +408,22 @@
 
         FontManager fm = FontManagerFactory.getInstance();
         CompositeFont dialog2D =
-          (CompositeFont) fm.findFont2D("dialog", font.getStyle(), FontManager.NO_FALLBACK);
+          (CompositeFont) fm.findFont2D("dialog", font.getStyle(),
+                                        FontManager.NO_FALLBACK);
         if (dialog2D == null) { /* shouldn't happen */
             return fuir;
         }
         PhysicalFont physicalFont = (PhysicalFont)font2D;
-        CompositeFont compFont = new CompositeFont(physicalFont, dialog2D);
+        ConcurrentHashMap<PhysicalFont, CompositeFont> compMap = compMapRef.get();
+        if (compMap == null) { // Its been collected.
+            compMap = new ConcurrentHashMap<PhysicalFont, CompositeFont>();
+            compMapRef = new SoftReference(compMap);
+        }
+        CompositeFont compFont = compMap.get(physicalFont);
+        if (compFont == null) {
+            compFont = new CompositeFont(physicalFont, dialog2D);
+            compMap.put(physicalFont, compFont);
+        }
         FontAccess.getFontAccess().setFont2D(fuir, compFont.handle);
         /* marking this as a created font is needed as only created fonts
          * copy their creator's handles.