Wednesday, April 22, 2015

JMeter - configuration of Cookie Manager, solution for spike up to 25% for a single user, Session event listener threw exception

Project Name: XXXXXXXXX
Application Type: Web based Mobile application framework

1. Problem

The session was not being handled efficiently in JMeter when we use the default configuration of Cookie Manager.

Solution:

On debugging the script I found an alternative method to handle session using the Cookie Manager.


The Cookie Policy was changed to “Default” and user defined cookies were manually added.

Default Cookie Manager Setting: 


Modified Cookie Manager Setting: 


2. Problem:
The CPU used to spike up to 25% for a single user. With the help of Jprofiler it was seen that around 40% of the execution time was being consumed by org.codehaus.jackson.map.ObjectMapper.writeValueAsString and org.codehaus.jackson.map.ObjectMapper.readValue.



Solution:

The following alternate methods were used in the code in order to rectify the issue:
GECAItem
getGECADataServices() --> to get services

GECAItemAttribute
getGECAItemValue() --> to get attribute value

GECAItemAttributeTrait --> to get attribute trait value
getAttributeTraitValue()


GECAPresentationAttribute --> to get presentation attribute value
getGECAPresentationAttributeValue()

GECAServiceParameter -->to get parameter value
getServiceParameterValue()

3. Problem:
The following error was found in the application logs while executing the load test for 20 concurrent users.

SEVERE: Session event listener threw exception
java.util.ConcurrentModificationException
               at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)


Solution:

On analysis we found that a possible solution to avoid the ConcurrentModificationException is to implement Synchronization of threads in the code.

This was done by implementing the following in the code :
Map<String,Object> sessionMap = Collections.synchronizedMap(new HashMap<String,Object>());

Detailed description of above Solution : 

If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:
   Map m = Collections.synchronizedMap(new HashMap(...));


4. Problem:
The application crashed on a concurrent load of 20 users after 20 min of the test run.

The application logs had the following error:
SEVERE:Servlet.service() for servlet appServlet threw exception
java.lang.StackOverflowError
                at java.util.Hashtable.get(Hashtable.java:334)
                at java.util.Properties.getProperty(Properties.java:932)
                at java.util.Properties.getProperty(Properties.java:934)
Solution :
Memory allocation/memory leakage/garbage collection issue. to be handled by DB team.