We are using Spring 2.0.3 and Hibernate 3.2.2 in Weblogic 10 MP1 Application server and frequently we are getting OutOfMemoryError.
After analyzing the heap dump we found that the objects of the class org.hibernate.impl.SessionFactoryObjectFactory hold the major chunk of the memory.
This object contains instances of org.hibernate.util.FastHashMap containing hashmaps and each hashmap has instances of org.hibernate.impl.SessionFactoryImpl.
I ma using the Eclipse Memory Analyser tool for memory analysis.
I have looked at the forums before posting the query but the only issue I could find was this one although it was not of much help -
http://forum.springsource.org/showthread.php?t=89569I have also had a look at the documentation
http://static.springsource.org/spring/d ... e/orm.html - Chapter 12 to verify the implementation. We are using cglib-2.1.3 as a part of the dependent libraries of hibernate
As reported in the Hibernate forums there was a memory leak in Hibernate 3.2.2 hence we migrated to Hibernate 3.2.6.
Refer
http://opensource.atlassian.com/project ... e/HHH-2481 and
http://forum.hibernate.org/viewtopic.php?t=968853 Inspite of the migration the memory leak still persists.
We are using HibernateTemplate, HibernateDaoSupport and org.springframework.transaction.interceptor.TransactionProxyFactoryBean instead of a standard AOP ProxyFactoryBean with a separate TransactionInterceptor definition.
Please find the abstract DAO class below using HibernateTemplate and HibernateDaoSupport
Code:
BaseHibernateDAO.java
Code:
public abstract class BaseHibernateDAO extends HibernateDaoSupport implements
DAO {
private static final AppLog LOG = LogFactory
.getLogger(BaseHibernateDAO.class);
public Serializable saveObject(final BaseBO obj) throws DataAccessException {
Object[] params = { obj };
LOG.entering("saveObject", params);
Serializable pk = null;
try {
pk = getHibernateTemplate().save(obj);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while inserting record", e);
}
LOG.exiting("saveObject", pk);
return pk;
}
public BaseBO getObject(final Class clazz, final Serializable pk)
throws DataAccessException {
Object[] params = { clazz, pk };
LOG.entering("getObject", params);
BaseBO obj = null;
try {
LOG.debug("key"+pk);
LOG.debug("class"+clazz);
obj = (BaseBO) getHibernateTemplate().get(clazz, pk);
LOG.debug("Object"+obj.toString());
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while inserting record", e);
}
LOG.entering("getObject", obj);
return obj;
}
public void updateObject(final BaseBO obj) throws DataAccessException {
Object[] params = { obj };
LOG.entering("updateObject", params);
try {
getHibernateTemplate().update(obj);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while updating record", e);
}
LOG.exiting("updateObject");
}
public void deleteObject(final BaseBO obj) throws DataAccessException {
Object[] params = { obj };
LOG.entering("deleteObject", params);
try {
getHibernateTemplate().delete(obj);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while deleting record", e);
}
LOG.exiting("deleteObject");
}
public List getAllObjects(final Class clazz) throws DataAccessException {
Object[] params = { clazz };
LOG.entering("getAll", params);
List list = null;
try {
list = (List) getHibernateTemplate().loadAll(clazz);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while fetching record", e);
}
LOG.entering("getAll", list);
return list;
}
public List getByNamedQuery(final String queryName, final Object[] values)
throws DataAccessException {
Object[] params = { queryName, values };
LOG.entering("getByNamedQuery", params);
List list = null;
try {
LOG.debug("Query Name"+queryName);
LOG.debug("Object"+values.toString());
list = (List) getHibernateTemplate().findByNamedQuery(queryName,
values);
LOG.debug("ListValue..."+list);
}catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while fetching record", e);
}
LOG.entering("getByNamedQuery", list);
return list;
}
public void saveOrUpdateObject(final BaseBO obj) throws DataAccessException {
Object[] params = { obj };
LOG.entering("saveOrUpdateObject", params);
try {
getHibernateTemplate().saveOrUpdate(obj);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException(
"Error while inserting/updating record", e);
}
LOG.exiting("saveOrUpdateObject");
}
public void UpdateOjectByValue(String entityName,BaseBO obj) throws DataAccessException {
Object[] params = { obj };
LOG.entering("UpdateOjectByValue", params);
try {
getHibernateTemplate().saveOrUpdate(entityName, obj);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException(
"Error while updating record", e);
}
LOG.exiting("UpdateObjectByValue");
}
public List getByQuery(final String queryName) throws DataAccessException {
Object[] params = { queryName};
LOG.entering("getByNamedQuery", params);
List list = null;
try {
list = (List) getHibernateTemplate().findByNamedQuery(queryName);
}catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while fetching record", e);
}
LOG.entering("getByNamedQuery", list);
return list;
}
public List getByHQL(final String queryString) throws DataAccessException {
Object[] params = { queryString };
LOG.entering("getByHQL", params);
List list = null;
try {
list = (List) getHibernateTemplate().find(queryString);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while fetching record", e);
}
LOG.entering("getByHQL", list);
return list;
}
public List getByHQL(final String queryString, final Object qParams[]) throws DataAccessException {
Object[] params = { queryString };
LOG.entering("getByHQL", params);
List list = null;
try {
list = (List) getHibernateTemplate().find(queryString, qParams);
} catch (org.springframework.dao.DataAccessException e) {
LOG.error(e, e.getCause());
throw new DataAccessException("Error while fetching record", e);
}
LOG.entering("getByHQL", list);
return list;
}
}
From the hibernate debug logs I could find the following details as follows
No. of opened session at timestamp statements = No. of closing session statements
No. of preparing statement lines = No. of closing statement lines
There are a lot of calls to instantiated session factory in the logs
Please find a sample hibernate logs below
Code:
2010-07-20 11:01:59,384] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.impl.SessionImpl opened session at timestamp: 12796201191
2010-07-20 11:01:59,402] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.query.QueryPlanCache unable to locate HQL query plan in cache; generating ( from GroupDetailsBO groupDetails where groupDetails.groupStatus in ( 'PDR' ))
[2010-07-20 11:01:59,455] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.hql.classic.QueryTranslatorImpl compiling query
2010-07-20 11:01:59,577] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.query.HQLQueryPlan HQL param location recognition took 5 mills ( from GroupDetailsBO groupDetails where groupDetails.groupStatus in ( 'PDR' ))
[2010-07-20 11:01:59,608] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.query.QueryPlanCache located HQL query plan in cache ( from GroupDetailsBO groupDetails where groupDetails.groupStatus in ( 'PDR' ))
[2010-07-20 11:01:59,608] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.query.HQLQueryPlan find: from GroupDetailsBO groupDetails where groupDetails.groupStatus in ( 'PDR' )
[2010-07-20 11:01:59,614] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.QueryParameters named parameters: {}
[2010-07-20 11:01:59,624] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.hql.classic.QueryTranslatorImpl HQL: from uk.co.o2.nemo.member.bo.GroupDetailsBO groupDetails where groupDetails.groupStatus in ( 'PDR' )
[2010-07-20 11:01:59,624] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.hql.classic.QueryTranslatorImpl SQL: select groupdetai0_.GROUP_ID as GROUP1_77_, groupdetai0_.GROUP_CLASSIFIER_ID as GROUP2_77_, groupdetai0_.GROUP_TYPE_ID as GROUP3_77_, groupdetai0_.GROUP_NAME as GROUP4_77_, groupdetai0_.OWNER_MPN as OWNER5_77_, groupdetai0_.START_DATE as START6_77_, groupdetai0_.END_DATE as END7_77_, groupdetai0_.ENDING_REASON as ENDING8_77_, groupdetai0_.GROUP_STATUS as GROUP9_77_ from TBL_GROUP groupdetai0_ where (groupdetai0_.GROUP_STATUS in('PDR'))
[2010-07-20 11:01:59,625] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
[2010-07-20 11:01:59,625] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.ConnectionManager opening JDBC connection
[2010-07-20 11:01:59,626] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.SQL select groupdetai0_.GROUP_ID as GROUP1_77_, groupdetai0_.GROUP_CLASSIFIER_ID as GROUP2_77_, groupdetai0_.GROUP_TYPE_ID as GROUP3_77_, groupdetai0_.GROUP_NAME as GROUP4_77_, groupdetai0_.OWNER_MPN as OWNER5_77_, groupdetai0_.START_DATE as START6_77_, groupdetai0_.END_DATE as END7_77_, groupdetai0_.ENDING_REASON as ENDING8_77_, groupdetai0_.GROUP_STATUS as GROUP9_77_ from TBL_GROUP groupdetai0_ where (groupdetai0_.GROUP_STATUS in('PDR'))
[2010-07-20 11:01:59,626] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher preparing statement
[2010-07-20 11:02:00,313] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher about to open ResultSet (open ResultSets: 0, globally: 0)
[2010-07-20 11:02:00,318] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.loader.Loader processing result set
[2010-07-20 11:02:00,319] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.loader.Loader done processing result set (0 rows)
[2010-07-20 11:02:00,319] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher about to close ResultSet (open ResultSets: 1, globally: 1)
[2010-07-20 11:02:00,320] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
[2010-07-20 11:02:00,320] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.AbstractBatcher closing statement
[2010-07-20 11:02:00,330] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.loader.Loader total objects hydrated: 0
[2010-07-20 11:02:00,330] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.engine.StatefulPersistenceContext initializing non-lazy collections
[2010-07-20 11:02:00,338] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.JDBCContext after autocommit
[2010-07-20 11:02:00,339] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.ConnectionManager transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
[2010-07-20 11:02:00,339] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.impl.SessionImpl after transaction completion
[2010-07-20 11:02:00,340] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.impl.SessionImpl closing session
[2010-07-20 11:02:00,340] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.ConnectionManager performing cleanup
[2010-07-20 11:02:00,341] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.ConnectionManager releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
[2010-07-20 11:02:00,346] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.JDBCContext after transaction completion
[2010-07-20 11:02:00,347] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.jdbc.ConnectionManager transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
[2010-07-20 11:02:00,347] [DEBUG] [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.hibernate.impl.SessionImpl after transaction completion
Please can you point me in the right direction.