Author: kkolinko
Date: Wed Apr 18 20:34:02 2012
New Revision: 1327670

URL: http://svn.apache.org/viewvc?rev=1327670&view=rev
Log:
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/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java

Modified: tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java?rev=1327670&r1=1327669&r2=1327670&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java Wed 
Apr 18 20:34:02 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);
             }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to