Author: kkolinko Date: Wed Apr 18 21:01:30 2012 New Revision: 1327680 URL: http://svn.apache.org/viewvc?rev=1327680&view=rev Log: Merged revision 1327670 from tomcat/trunk: Save a bit of memory in annotations cache in DefaultInstanceManager occupied by unused entries in annotation lists.
I could do the same by calling ArrayList.trimToSize(), preserving the Lists abstraction, but 1). That involves the same array copying operation as toArray() call that I am using, 2). I do not see any benefits from using List here, as the only operation with annotations list after it has been created is iterating over it. Thus I preferred to replace lists with explicit arrays. Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1327670 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java?rev=1327680&r1=1327679&r2=1327680&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java Wed Apr 18 21:01:30 2012 @@ -30,7 +30,6 @@ import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; @@ -69,8 +68,12 @@ public class DefaultInstanceManager impl private final Properties restrictedFilters = new Properties(); private final Properties restrictedListeners = new Properties(); private final Properties restrictedServlets = new Properties(); - private final Map<Class<?>,List<AnnotationCacheEntry>> annotationCache = - new WeakHashMap<Class<?>, List<AnnotationCacheEntry>>(); + private final Map<Class<?>, AnnotationCacheEntry[]> annotationCache = + new WeakHashMap<Class<?>, AnnotationCacheEntry[]>(); + + // Used when there are no annotations in a class + private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY + = new AnnotationCacheEntry[0]; public DefaultInstanceManager(Context context, Map<String, Map<String, String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader containerClassLoader) { classLoader = catalinaContext.getLoader().getClassLoader(); @@ -177,7 +180,7 @@ public class DefaultInstanceManager impl // At the end the postconstruct annotated // method is invoked - List<AnnotationCacheEntry> annotations; + AnnotationCacheEntry[] annotations; synchronized (annotationCache) { annotations = annotationCache.get(clazz); } @@ -213,7 +216,7 @@ public class DefaultInstanceManager impl // At the end the postconstruct annotated // method is invoked - List<AnnotationCacheEntry> annotations = null; + AnnotationCacheEntry[] annotations = null; synchronized (annotationCache) { annotations = annotationCache.get(clazz); } @@ -251,13 +254,19 @@ public class DefaultInstanceManager impl Map<String, String> injections) throws IllegalAccessException, InvocationTargetException, NamingException { + List<AnnotationCacheEntry> annotations = null; + while (clazz != null) { - List<AnnotationCacheEntry> annotations = null; + AnnotationCacheEntry[] annotationsArray = null; synchronized (annotationCache) { - annotations = annotationCache.get(clazz); + annotationsArray = annotationCache.get(clazz); } - if (annotations == null) { - annotations = new ArrayList<AnnotationCacheEntry>(); + if (annotationsArray == null) { + if (annotations == null) { + annotations = new ArrayList<AnnotationCacheEntry>(); + } else { + annotations.clear(); + } if (context != null) { // Initialize fields annotations for resource injection if @@ -421,12 +430,15 @@ public class DefaultInstanceManager impl preDestroy.getParameterTypes(), null, AnnotationCacheEntryType.PRE_DESTROY)); } - if (annotations.size() == 0) { - // Use common empty list to save memory - annotations = Collections.emptyList(); + if (annotations.isEmpty()) { + // Use common object to save memory + annotationsArray = ANNOTATIONS_EMPTY; + } else { + annotationsArray = annotations.toArray( + new AnnotationCacheEntry[annotations.size()]); } synchronized (annotationCache) { - annotationCache.put(clazz, annotations); + annotationCache.put(clazz, annotationsArray); } } clazz = clazz.getSuperclass(); @@ -455,7 +467,7 @@ public class DefaultInstanceManager impl Class<?> clazz = instance.getClass(); while (clazz != null) { - List<AnnotationCacheEntry> annotations; + AnnotationCacheEntry[] annotations; synchronized (annotationCache) { annotations = annotationCache.get(clazz); } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1327680&r1=1327679&r2=1327680&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Apr 18 21:01:30 2012 @@ -75,6 +75,11 @@ <bug>53057</bug>: Add OpenSSL version number INFO log message when initializing. (schultz) </fix> + <update> + Save a bit of memory in annotations cache in + <code>DefaultInstanceManager</code> by trimming annotation lists + to their size. (kkolinko) + </update> </changelog> </subsection> <subsection name="Cluster"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org