使用JProfiler进行性能测试时发现如下情况:
在程式不停的运行中,query.list分配的内存不会被回收。不断创建新的instance.
是多线程运行的程序。
使用Query的方法如下:
public List find(String strhql) {
// TODO Auto-generated method stub
List result = null;
Session session = null;
Query query = null;
try {
session = this.getSession();
session.beginTransaction();
query = session.createQuery(strhql);
result = query.list();
session.getTransaction().commit();
session.flush();
session.clear();
session.close();
} catch (Exception e) {
session.getTransaction().rollback();
logger.debug("执行数据库中查询时失败,语句为:" + strhql, e);
} finally {
query = null;
this.closeSession(session);
}
return result;
}
有没有遇到过这种情况的朋友,有可行的解决方法么?
木有2级缓存我觉得可能就变2个了
检查下你[color=red]HibernateSessionFactory[/color]的构造方法,如果每次都是config之后new一个,那你就用完直接把sessionFactory也关了
然后看下你Impl包里面的THDservice,是不是有什么方法没有if做判断
一直叫getParam()
query.list(); 分配了新的内存地址 result是对这个内存的引用,能否回收是要看你的result的引用以及外层对result的引用什么时候消除,仔细检查一下,如果最外层的引用消除就能回收内存了。这不是hibernate的错。
List results = CollectionHelper.EMPTY_LIST;
public static final List EMPTY_LIST = Collections.unmodifiableList( new ArrayList(0) );
这是Hibernate里的源码,调用Query.list都会产生一个新的ArrayList,这是你没法控制的,除非你想要修改它,不过我觉得没有这样的必要,因为我想这在于你的程序的设计,多线程,你还希望Query.list返回单例,不太明白你的意图是?而且你所说的内存消耗过大的问题,我不觉得这真实存在,很多项目里面我都使用这个,但没有什么问题发生。
在你取出list.get(0)后手动设置result=null
[color=red]session = this.getSession(); [/color]
你用这种方法打开session,显然是让spring帮你管理了
你自己close不close都不会理你,而且你每次null一个Session
肯定新建一个instance啊。。。
贴你的配置文件
[color=red][quote]没有用Spring[/quote][/color]
大哥你也变通下嘛,hibernate配置扔出来看下啊
hibernate的 list()不释放,我个人觉得是它返回了proxy
相当于iterator方法给你的延时加载,然后等你调用它
但实际上你已经把需要的结果实例化给了result
(result你null不null都不重要,你flush不flush也不用要,clear不clear也不重要,只要你close了就行)
关闭session后 这个proxy并不会释放,因为放在2级缓存里了
好了,再次session,因为list()方法查询一级缓存后就直接找数据库了
压根不会找2级,你每次List result = query.list() 就会创一个proxy
但这个proxy完全不会被用到,也没有释放
另外要说的是,Hibernate 的list()default设置是不会返回proxy的
所以要看你配置文件 ! 明白?
朋友,你这个问题解决了吗,我都快愁死了!
这个问题解决了吗?求解决方法