You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jw...@apache.org on 2011/04/18 19:23:08 UTC

svn commit: r1094665 - in /myfaces/trinidad/trunk: src/site/xdoc/devguide/ trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/ trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/

Author: jwaldman
Date: Mon Apr 18 17:23:08 2011
New Revision: 1094665

URL: http://svn.apache.org/viewvc?rev=1094665&view=rev
Log:
TRINIDAD-2026 memory leak in skinstyleprovider
Added LRUCache. Default size is 20, and it is configurable with org.apache.myfaces.trinidad.skin.MAX_SKINS_CACHED

Modified:
    myfaces/trinidad/trunk/src/site/xdoc/devguide/skinning.xml
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts

Modified: myfaces/trinidad/trunk/src/site/xdoc/devguide/skinning.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/src/site/xdoc/devguide/skinning.xml?rev=1094665&r1=1094664&r2=1094665&view=diff
==============================================================================
--- myfaces/trinidad/trunk/src/site/xdoc/devguide/skinning.xml (original)
+++ myfaces/trinidad/trunk/src/site/xdoc/devguide/skinning.xml Mon Apr 18 17:23:08 2011
@@ -1263,6 +1263,13 @@ this resolves to
           
           </P>
         </subsection>  
+        <subsection name="Performance when many different skins in an application">
+        The skinning framework caches information for the generated css file for each skin that is requested. This
+        could be a source of a memory leak if your application is built to use many different skins, like each user has his own custom skin. Fortunately, this is not a common usecase.
+        In this case, you would want to limit the number of generated css files we cache in our LRUCache (least-recently used cache).
+        You can do this by specifying the maximum number of skins you want to cache with the web.xml context-param 
+        org.apache.myfaces.trinidad.skin.MAX_SKINS_CACHED
+         </subsection>
       </section>
       
       <a name="Custom_Component_Developers"></a>

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java?rev=1094665&r1=1094664&r2=1094665&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java Mon Apr 18 17:23:08 2011
@@ -18,9 +18,12 @@
  */
 package org.apache.myfaces.trinidadinternal.skin;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.faces.context.FacesContext;
+
 import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidadinternal.style.StyleContext;
 import org.apache.myfaces.trinidadinternal.style.StyleProvider;
@@ -28,6 +31,7 @@ import org.apache.myfaces.trinidadintern
 import org.apache.myfaces.trinidadinternal.style.xml.StyleSheetDocumentUtils;
 import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetDocument;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidadinternal.util.LRUCache;
 
 
 /**
@@ -228,6 +232,44 @@ public class SkinStyleProvider extends F
     // =-=ags For now, we just use a global variable.  But
     //        really, our cache should probably be hanging off
     //        of the ServletContext.
+    if (_sSharedProviders == null)
+    {
+      FacesContext context = FacesContext.getCurrentInstance();
+      String lruCacheSize =
+        context.getExternalContext().
+        getInitParameter(_MAX_SKINS_CACHED); 
+      
+      int lruCacheSizeInt = _MAX_SKINS_CACHED_DEFAULT;
+      boolean invalidInt = false;
+
+      if (lruCacheSize != null && !lruCacheSize.equals(""))
+      {
+        try
+        {
+          lruCacheSizeInt = Integer.parseInt(lruCacheSize);
+        }
+        catch (NumberFormatException nfe)
+        {
+          invalidInt = true;
+        }
+        if (lruCacheSizeInt <= 0)
+        {
+          invalidInt = true;
+        }
+      }
+      
+      // The user typed in an invalid integer ( <=0 or a value that couldn't be formatted to a number)
+      // so log a warning
+      if (invalidInt)
+      {
+        lruCacheSizeInt = _MAX_SKINS_CACHED_DEFAULT;
+        if (_LOG.isWarning())
+          _LOG.warning("INVALID_INTEGER_MAX_SKINS_CACHED", new Object[]{lruCacheSize, _MAX_SKINS_CACHED_DEFAULT});        
+      }
+        
+      _sSharedProviders = new LRUCache<ProviderKey, StyleProvider>(lruCacheSizeInt);
+    }
+
     return _sSharedProviders;
   }
 
@@ -288,13 +330,15 @@ public class SkinStyleProvider extends F
 
   // The Skin which provides styles
   private Skin _skin;
-
+  
   // The Skin-specific StyleSheetDocument
   private StyleSheetDocument _skinDocument;
 
   // Cache of shared SkinStyleProvider instances
-  private static final Map<ProviderKey, StyleProvider> _sSharedProviders =
-    new HashMap<ProviderKey, StyleProvider>(31);
+  private static Map<ProviderKey, StyleProvider> _sSharedProviders;
   private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
     SkinStyleProvider.class);
+  private static final String _MAX_SKINS_CACHED =
+    "org.apache.myfaces.trinidad.skin.MAX_SKINS_CACHED";
+  private static final int _MAX_SKINS_CACHED_DEFAULT = 20;
 }

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts?rev=1094665&r1=1094664&r2=1094665&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts Mon Apr 18 17:23:08 2011
@@ -896,6 +896,9 @@ The skin {0} specified on the requestMap
  <!-- NO_SKIN_SPECIFIED -->
  <resource key="NO_SKIN_SPECIFIED">No Skin specified.</resource>
 
+ <!-- INVALID_INTEGER_MAX_SKINS_CACHED -->
+ <resource key="INVALID_INTEGER_MAX_SKINS_CACHED">Invalid integer {0} for context-param org.apache.myfaces.trinidad.skin.MAX_SKINS_CACHED in web.xml, so the default integer {1} is used instead.</resource>
+
  <!-- NO_INPUTSTREAM -->
  <resource key="NO_INPUTSTREAM">Null inputStream</resource>