High GC load using Hibernate

I have developed a web application using Spring MVC + Hibernate and when running load tests it seems the Garbage Collector is being called too often. I am afraid it might have to do with the way I manage Hibernates session.

I have an AbstractDao which all of my DAO objects extends:

public class AbstractDaoHibernateImpl {

    protected GenericDataBaseExceptionHandler exceptionHandler;
    private SessionFactory sessionFactory;  

    public AbstractDaoHibernateImpl() {
    }

    public void setExceptionHandler(GenericDataBaseExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

}

In spring entity bean configuration I define each of my DAOs like this:

   <bean name="userDao" class="com.kelmer.dao.UserDaoImpl">
        <property name="sessionFactory" ref="SessionFactory" />
        <property name="exceptionHandler" ref="defaultSpringExceptionHandler" />
    </bean>

And then this is a sample method from one of my DAOs:

    @Override
    public EstacionVO findById(Long id) throws InstanceNotFoundException {
        User e = (User ) getSession().createQuery(SELECT_USER_BY_ID).setParameter("userId", id).uniqueResult();
        if (e == null) {
            throw new InstanceNotFoundException ("No user with provided Id", User.class);
        }
        return e;
    }

I honestly can see anything that might be causing a memory leak but then again I'm no real expert here. Am I doing session management right? I know I took the code from AbstractDao from some legacy code and I fear that's where the memory problem could be, since there is no explicit session closing or finalizing.

PS. For transaction management, I am using <tx:annotation-driven /> in spring context and annotating each method with @Transactional.

Answers


At first glance, there doesn't seem to be anything unusual in your code.

Run a performance monitor to see what objects are created.

Unless the problem is trivial, it's hard to see where performance is lost by just looking at the code and 90% of the time, any statement "it must be this" turns out to be wrong.


What is your hibernate session creation strategy. Is your code using the same session again and again? Instead of :

protected Session getSession() {
    return sessionFactory.getCurrentSession();
}

try opening a new session for each request:

protected Session getSession() {
    return sessionFactory.openSession();
}

Each session has a session cache to which all retrieved or persisted objects are added. If you keep on using the same session for querying many-many entities, it 'may' lead to such a scenario.

Give the change a try and do let us know if helps.

The right way

Use one of the performance monitoring tools to see what's really causing the issue: http://java.dzone.com/articles/java-performance-troubleshooti-0


Need Your Help

Do we need fixed point combinators in C#?

c# functional-programming lambda

I was playing with recursive lambdas in C# and have found two approaches to do this on the web. One approach uses fixed point combinator and the other does not. In the code below f1 is built using