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 comment

Blog at WordPress.com.