You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "André Næss (JIRA)" <de...@myfaces.apache.org> on 2007/06/05 10:28:26 UTC

[jira] Created: (MYFACES-1658) Memory leak in JspStateManagerImpl

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.


[jira] Resolved: (MYFACES-1658) Memory leak in JspStateManagerImpl

Posted by "Bruno Aranda (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-1658?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bruno Aranda resolved MYFACES-1658.
-----------------------------------

       Resolution: Fixed
    Fix Version/s: 1.2.0-SNAPSHOT
                    1.1.6-SNAPSHOT
         Assignee: Bruno Aranda

Resolved with the solution proposed by Thomas in this post:

http://www.nabble.com/Possible-memory-leak-in-JspStateManagerImpl-t3863826.html

Many thanks Andre for spotting and reporting the problem with detailed explanation and proposing a solution!

> 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
>            Assignee: Bruno Aranda
>             Fix For:  1.1.6-SNAPSHOT, 1.2.0-SNAPSHOT
>
>
> 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.