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.