0 0

SSH系统,调用HibernateTemplate.find()方法的时候,会导致内存泄露?5

spring2.0.2 hibernate3.1.2 struts2.0.6,web应用运行一段时间之后,内存使用会越来越大直到outofmemory。
后来测试发现,所有的dao调用了HibernateTemplate.find()之后,内存中就会有org.hibernate.hql.ast.* 这个包中的对象常驻内存,Full gc也不能完全回收(所有用户退出,无活动的session存在)。
以下是我的代码和配置文件,请指教。
基类BaseDao的片段
public Object getObject(Class clazz, String[] fields, Object[] values) {
		List list = getObjectList(clazz, fields, values);
		return (list.size() > 0) ? list.get(0) : null;
	}

Service调用
Depot depot = (Depot) depotDao.getObject(Depot.class, new String[] {
				"phoneNumber", "depotId.ringIndex" }, new Object[] {
				portalUser.getPhoneNumber(), ringIndex });

		if (depot == null) {
			return null;
		}
                  //该方法调用HibernateTemplate.get()获取结果
		Ring ring = ringDao.getRing(depot.getDepotId().getRingIndex());
		depot.setChargeable(ring);

		return depot;
}

所有的service方法都定义了事务
service只要调用该方法,就会导致org.hibernate.hql.ast.* 包中的一些对象常驻内存。

我不知道hibernate是不是运用了对象池对这些对象进行缓存。如果有的话,也不可能达到100w的级别吧?
我的web应用outofmemory的时候,一般这个时候这个包的对象的总数是百万级别。

再次谢谢指教


问题补充:
从我用Jprofiler监测的结果看HibernateTemplate的get(),load()方法都没有问题,只有在调用find的时候会生成一些hql解析的中间变量没有回收回来。

问题补充:
问题已经解决,是因为自己编写的DAO基类有拼装HQL的行为,而且不是采用的参数化的HQL,所以导致每次查询的时候都会是一条不同的HQL(hibernate会缓存hql的解析结果,应该是通过hql做为Key值来保存)这样hibernate就会保存很多hql的缓存。导致系统运行时间长了之后,内存逐渐被占用直到最后的oom。

谢谢大家的关注,我关闭问题了。
2008年7月18日 18:08

1个答案 按时间排序 按投票排序

0 0

关注,建议看看HibernateTemplate.get()方法的原码,看他里面用什么Hibernate的方法再找原因!

2008年7月19日 10:06

相关推荐

Global site tag (gtag.js) - Google Analytics