Memory leak in JspStateManagerImpl
----------------------------------

                 Key: MYFACES-1658
                 URL: https://issues.apache.org/jira/browse/MYFACES-1658
             Project: MyFaces Core
          Issue Type: Bug
          Components: General
    Affects Versions: 1.1.5
         Environment: JDK1.5, using Tomcat 5.5.
            Reporter: André Næss


We are working on a JSF project and recently started stress testing the system. 
This stress-testing caused the JVM to run out of memory and spend most of it 
time  doing Full GC. Analyzing the heap revealed that most of the memory was 
being retained by SerializedViewCollection instances. We also noticed that the 
value of NUMBER_OF_VIEWS_IN_SESSION didn't seem to affect the memory usage.

It seems the problem is due to the _oldSerializedViews hashmap which is 
supposed to use soft references and hence be GC-ed whenever there is a lack of 
memory, but this apparently doesn't work. Removing this hashmap completely 
solved the problem. It is however difficult to provide a simple testcase as we 
used JMeter to load the server with 600 users fetching a fairly big JSF page 
with a constant throughput of 20 requests per second.

I should also mention that we found this problem with 1.1.4 but I fixed it with 
the 1.1.5 release.

Here's the diff output:

~/code/myfaces-1.1.5/impl/src/main/java/org/apache/myfaces/application/jsp$ svn 
diff
Index: JspStateManagerImpl.java
===================================================================
--- JspStateManagerImpl.java    (revision 543859)
+++ JspStateManagerImpl.java    (working copy)
@@ -18,7 +18,6 @@
  */
 package org.apache.myfaces.application.jsp;

-import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 import org.apache.commons.logging.Log;
@@ -609,10 +608,6 @@
         private final List _keys = new 
ArrayList(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
         private final Map _serializedViews = new HashMap();

-        // old views will be hold as soft references which will be removed by
-        // the garbage collector if free memory is low
-        private transient Map _oldSerializedViews = null;
-
         public synchronized void add(FacesContext context, Object state) {
             Object key = new SerializedViewKey(context);
             _serializedViews.put(key, state);
@@ -623,10 +618,7 @@
             int views = getNumberOfViewsInSession(context);
             while (_keys.size() > views) {
                 key = _keys.remove(0);
-                Object oldView = _serializedViews.remove(key);
-                if (oldView != null) {
-                    getOldSerializedViewsMap().put(key, oldView);
-                }
+                _serializedViews.remove(key);
             }
         }

@@ -660,23 +652,9 @@
             return views;
         }

-        /**
-         * @return old serialized views map
-         */
-        protected Map getOldSerializedViewsMap() {
-            if (_oldSerializedViews == null) {
-                _oldSerializedViews = new ReferenceMap();
-            }
-            return _oldSerializedViews;
-        }
-
         public Object get(Integer sequence, String viewId) {
             Object key = new SerializedViewKey(viewId, sequence);
-            Object value = _serializedViews.get(key);
-            if (value == null) {
-                value = getOldSerializedViewsMap().get(key);
-            }
-            return value;
+            return _serializedViews.get(key);
         }
     }



-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to