Monitoring HttpSession memory leak during JavaEE development

In my previous post I have provided a sample servlet filter to monitor non-serializable objects in HttpSession to make the JavaEE application compatible for clustered environment. We have enhanced the same servlet filter to log HttpSession object size which is helping us to find the memory leak during the development.

Here is the Java code

package org.webmoli.servlets;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class HttpSessionFilter implements Filter {

	private boolean testSerializability;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		testSerializability = Boolean.valueOf(filterConfig.getInitParameter("testSerializability"));
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		chain.doFilter(request, response);
		// this block of code ensures all the values in the HttpSession object are serializable to ensure it works on
		// clustered environment
		if (testSerializability) {
			HttpServletRequest httpServletRequest = (HttpServletRequest) request;
			HttpSession httpSession = httpServletRequest.getSession(false);
			if (httpSession != null) {
				Enumeration<?> enumeration = httpSession.getAttributeNames();
				int totalSize = 0;
				while (enumeration.hasMoreElements()) {
					Object value = httpSession.getAttribute((String) enumeration.nextElement());
					if (value != null) {
						try {
							totalSize = totalSize + sizeof(value);
						} catch (Exception exp) {
							exp.printStackTrace();
							throw new RuntimeException(exp.getMessage());
						}
					}
				}
				System.out.println(String.format("Size of the session object is: %d KB", +(totalSize * 1f / 1024)));
			}
		}
	}

	@Override
	public void destroy() {

	}

	public static int sizeof(Object obj) throws IOException {
		ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
		objectOutputStream.writeObject(obj);
		objectOutputStream.flush();
		objectOutputStream.close();
		return byteOutputStream.toByteArray().length;
	}
}

The web.xml entry looks like below.

<filter>
<filter-name>HttpSessionFilter</filter-name>
<filter-class>org.webmoli.servlets.HttpSessionFilter</filter-class>
<init-param>
<param-name>testSerializability</param-name>
<!-- Make the below value as false in production environment -->
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HttpSessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: