ASF Bugzilla – Attachment 19542 Details for
Bug 31789
Memory leak in ELEvaluator
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
SPI like fix for this issue, 17700 and 32311
StandardTaglibPoolingStrategy.patch (text/plain), 13.88 KB, created by
Henri Yandell
on 2007-02-07 17:32:21 UTC
(
hide
)
Description:
SPI like fix for this issue, 17700 and 32311
Filename:
MIME Type:
Creator:
Henri Yandell
Created:
2007-02-07 17:32:21 UTC
Size:
13.88 KB
patch
obsolete
>Index: src/org/apache/taglibs/standard/lang/jstl/Constants.java >=================================================================== >--- src/org/apache/taglibs/standard/lang/jstl/Constants.java (revision 504759) >+++ src/org/apache/taglibs/standard/lang/jstl/Constants.java (working copy) >@@ -33,6 +33,18 @@ > public class Constants > { > //------------------------------------- >+ // SPI extensions >+ >+ public static final String ELEVALUATOR_EXPECTED_STRINGS_CACHE = >+ "org.apache.taglibs.standard.elevalutor.expected.strings.cache"; >+ public static final String ELEVALUATOR_EXPECTED_TYPES_CACHE = >+ "org.apache.taglibs.standard.elevalutor.expected.types.cache"; >+ public static final String MESSAGEFORMAT_CACHE = >+ "org.apache.taglibs.standard.messageformat.cache"; >+ public static final String DATEFORMAT_CACHE = >+ "org.apache.taglibs.standard.dateformat.cache"; >+ >+ //------------------------------------- > // Resources > > static ResourceBundle sResources = >Index: src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java >=================================================================== >--- src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (revision 504759) >+++ src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (working copy) >@@ -28,6 +28,8 @@ > import org.apache.taglibs.standard.lang.jstl.parser.Token; > import org.apache.taglibs.standard.lang.jstl.parser.TokenMgrError; > >+import org.apache.taglibs.standard.util.*; >+ > /** > * > * <p>This is the main class for evaluating expression Strings. An >@@ -91,12 +93,19 @@ > > /** The mapping from expression String to its parsed form (String, > Expression, or ExpressionString) **/ >- static Map sCachedExpressionStrings = >- Collections.synchronizedMap (new HashMap ()); >+ static StandardTaglibCache sCachedExpressionStrings = >+ StandardTaglibCacheFactory.createCache( >+ Constants.ELEVALUATOR_EXPECTED_STRINGS_CACHE, >+ ForeverStandardTaglibCache.class >+ ); > > /** The mapping from ExpectedType to Maps mapping literal String to > parsed value **/ >- static Map sCachedExpectedTypes = new HashMap (); >+ static StandardTaglibCache sCachedExpectedTypes = >+ StandardTaglibCacheFactory.createCache( >+ Constants.ELEVALUATOR_EXPECTED_TYPES_CACHE, >+ ForeverStandardTaglibCache.class >+ ); > > /** The static Logger **/ > static Logger sLogger = new Logger (System.out); >@@ -104,9 +113,6 @@ > /** The VariableResolver **/ > VariableResolver mResolver; > >- /** Flag if the cache should be bypassed **/ >- boolean mBypassCache; >- > //------------------------------------- > /** > * >@@ -124,25 +130,6 @@ > //------------------------------------- > /** > * >- * Constructor >- * >- * @param pResolver the object that should be used to resolve >- * variable names encountered in expressions. If null, all variable >- * references will resolve to null. >- * >- * @param pBypassCache flag indicating if the cache should be >- * bypassed >- **/ >- public ELEvaluator (VariableResolver pResolver, >- boolean pBypassCache) >- { >- mResolver = pResolver; >- mBypassCache = pBypassCache; >- } >- >- //------------------------------------- >- /** >- * > * Evaluates the given expression String > * > * @param pExpressionString the expression String to be evaluated >@@ -248,10 +235,7 @@ > } > > // See if it's in the cache >- Object ret = >- mBypassCache ? >- null : >- sCachedExpressionStrings.get (pExpressionString); >+ Object ret = sCachedExpressionStrings.get (pExpressionString); > > if (ret == null) { > // Parse the expression >@@ -311,8 +295,7 @@ > > // Find the cached value > Map valueByString = getOrCreateExpectedTypeMap (pExpectedType); >- if (!mBypassCache && >- valueByString.containsKey (pValue)) { >+ if (valueByString.containsKey (pValue)) { > return valueByString.get (pValue); > } > else { >@@ -331,14 +314,12 @@ > **/ > static Map getOrCreateExpectedTypeMap (Class pExpectedType) > { >- synchronized (sCachedExpectedTypes) { > Map ret = (Map) sCachedExpectedTypes.get (pExpectedType); > if (ret == null) { > ret = Collections.synchronizedMap (new HashMap ()); > sCachedExpectedTypes.put (pExpectedType, ret); > } > return ret; >- } > } > > //------------------------------------- >Index: src/org/apache/taglibs/standard/resources/Resources.java >=================================================================== >--- src/org/apache/taglibs/standard/resources/Resources.java (revision 504759) >+++ src/org/apache/taglibs/standard/resources/Resources.java (working copy) >@@ -20,6 +20,9 @@ > import java.util.MissingResourceException; > import java.util.ResourceBundle; > >+import org.apache.taglibs.standard.util.*; >+import org.apache.taglibs.standard.lang.jstl.Constants; >+ > /** > * <p>Provides locale-neutral access to string resources. Only the > * documentation and code are in English. :-) >@@ -52,7 +55,10 @@ > private static ResourceBundle rb = > ResourceBundle.getBundle(RESOURCE_LOCATION); > >+ private static StandardTaglibCache messageFormatCache = >+ StandardTaglibCacheFactory.createCache(Constants.MESSAGEFORMAT_CACHE); > >+ > //********************************************************************* > // Public static methods > >@@ -66,7 +72,12 @@ > public static String getMessage(String name, Object[] a) > throws MissingResourceException { > String res = rb.getString(name); >- return MessageFormat.format(res, a); >+ MessageFormat msgFormat = (MessageFormat) messageFormatCache.get(res); >+ if(msgFormat == null) { >+ msgFormat = new MessageFormat(res); >+ messageFormatCache.put(res, msgFormat); >+ } >+ return msgFormat.format(res, a); > } > > /** Retrieves a message with one argument. */ >Index: src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java >=================================================================== >--- src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (revision 504759) >+++ src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (working copy) >@@ -31,6 +31,9 @@ > import org.apache.taglibs.standard.resources.Resources; > import org.apache.taglibs.standard.tag.common.core.Util; > >+import org.apache.taglibs.standard.util.*; >+import org.apache.taglibs.standard.lang.jstl.Constants; >+ > /** > * Support for tag handlers for <formatDate>, the date and time > * formatting tag in JSTL 1.0. >@@ -65,6 +68,8 @@ > private String var; // 'var' attribute > private int scope; // 'scope' attribute > >+ private static StandardTaglibCache dateFormatCache = >+ StandardTaglibCacheFactory.createCache(Constants.DATEFORMAT_CACHE); > > //********************************************************************* > // Constructor and initialization >@@ -183,20 +188,32 @@ > private DateFormat createFormatter(Locale loc) throws JspException { > DateFormat formatter = null; > >- if ((type == null) || DATE.equalsIgnoreCase(type)) { >- formatter = DateFormat.getDateInstance( >- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"), >- loc); >- } else if (TIME.equalsIgnoreCase(type)) { >- formatter = DateFormat.getTimeInstance( >- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"), >- loc); >- } else if (DATETIME.equalsIgnoreCase(type)) { >- formatter = DateFormat.getDateTimeInstance( >- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"), >- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"), >- loc); >- } else { >+ if ((type == null) || DATE.equalsIgnoreCase(type)) { >+ int style = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"); >+ String key = DATE + style + loc; >+ formatter = (DateFormat) dateFormatCache.get(key); >+ if(formatter == null) { >+ formatter = DateFormat.getDateInstance(style, loc); >+ dateFormatCache.put(key, formatter); >+ } >+ } else if (TIME.equalsIgnoreCase(type)) { >+ int style = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"); >+ String key = TIME + style + loc; >+ formatter = (DateFormat) dateFormatCache.get(key); >+ if(formatter == null) { >+ formatter = DateFormat.getTimeInstance(style, loc); >+ dateFormatCache.put(key, formatter); >+ } >+ } else if (DATETIME.equalsIgnoreCase(type)) { >+ int style1 = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"); >+ int style2 = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"); >+ String key = DATETIME + style1 + loc + style2; >+ formatter = (DateFormat) dateFormatCache.get(key); >+ if(formatter == null) { >+ formatter = DateFormat.getDateTimeInstance(style1, style2, loc); >+ dateFormatCache.put(key, formatter); >+ } >+ } else { > throw new JspException( > Resources.getMessage("FORMAT_DATE_INVALID_TYPE", > type)); >@@ -204,4 +221,5 @@ > > return formatter; > } >+ > } >Index: src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java >=================================================================== >--- src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java (revision 0) >+++ src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java (revision 0) >@@ -0,0 +1,44 @@ >+package org.apache.taglibs.standard.util; >+ >+public class StandardTaglibCacheFactory { >+ >+ /** >+ * @throws ClassNotFoundException >+ * @throws InstantiationException >+ * @throws IllegalAccessException >+ */ >+ public static StandardTaglibCache createCache(String key) { >+ return createCache(key, null); >+ } >+ >+ /** >+ * @throws ClassNotFoundException >+ * @throws InstantiationException >+ * @throws IllegalAccessException >+ */ >+ public static StandardTaglibCache createCache(String key, Class defaultClass) { >+ >+ String className = System.getProperty(key); >+ >+ try { >+ if(className == null) { >+ if(defaultClass == null) { >+ return null; >+ } else { >+ return (StandardTaglibCache) defaultClass.newInstance(); >+ } >+ } >+ >+ return (StandardTaglibCache) Class.forName(className, true, >+ Thread.currentThread().getContextClassLoader() >+ ).newInstance(); >+ } catch(ClassNotFoundException cnfe) { >+ throw new RuntimeException("Unable to create cache: " + cnfe); >+ } catch(IllegalAccessException iae) { >+ throw new RuntimeException("Unable to create cache: " + iae); >+ } catch(InstantiationException ie) { >+ throw new RuntimeException("Unable to create cache: " + ie); >+ } >+ } >+ >+} > >Property changes on: src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java >___________________________________________________________________ >Name: svn:eol-style > + native > >Index: src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java >=================================================================== >--- src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java (revision 0) >+++ src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java (revision 0) >@@ -0,0 +1,22 @@ >+package org.apache.taglibs.standard.util; >+ >+import java.util.Collections; >+import java.util.HashMap; >+import java.util.Map; >+ >+/** >+ * Objects are cached forever in a Forever cache. >+ */ >+public class ForeverStandardTaglibCache implements StandardTaglibCache { >+ >+ private Map map = Collections.synchronizedMap( new HashMap() ); >+ >+ public Object get(Object key) { >+ return map.get(key); >+ } >+ >+ public void put(Object key, Object value) { >+ map.put(key, value); >+ } >+ >+} > >Property changes on: src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java >___________________________________________________________________ >Name: svn:eol-style > + native > >Index: src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java >=================================================================== >--- src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java (revision 0) >+++ src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java (revision 0) >@@ -0,0 +1,15 @@ >+package org.apache.taglibs.standard.util; >+ >+/** >+ * Objects are never cached. >+ */ >+public class NullStandardTaglibCache implements StandardTaglibCache { >+ >+ public Object get(Object key) { >+ return null; >+ } >+ >+ public void put(Object key, Object value) { >+ } >+ >+} > >Property changes on: src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java >___________________________________________________________________ >Name: svn:eol-style > + native > >Index: src/org/apache/taglibs/standard/util/StandardTaglibCache.java >=================================================================== >--- src/org/apache/taglibs/standard/util/StandardTaglibCache.java (revision 0) >+++ src/org/apache/taglibs/standard/util/StandardTaglibCache.java (revision 0) >@@ -0,0 +1,26 @@ >+package org.apache.taglibs.standard.util; >+ >+/** >+ * There are various places in the Standard taglib that >+ * can really benefit from some caching, however implementing >+ * a cache with enough options to keep each user happy it >+ * beyond the scope of the Standard taglib. This interface >+ * is provided as a plugin point for different cache >+ * implementations. >+ */ >+public interface StandardTaglibCache { >+ >+ /** >+ * Get an object out of the cache. >+ * <code>null</code> is returned if there is nothing >+ * registered under the specified key. >+ */ >+ Object get(Object key); >+ >+ /** >+ * Register an object in the cache for a specified key. >+ * Passing in a value of <code>null</code> unregisters a key. >+ */ >+ void put(Object key, Object value); >+ >+} > >Property changes on: src/org/apache/taglibs/standard/util/StandardTaglibCache.java >___________________________________________________________________ >Name: svn:eol-style > + native >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 31789
:
13161
|
13162
|
13163
|
13189
|
13190
|
13191
|
13192
|
13193
|
19542
|
20701
|
20866
|
20868
|
20887