日期:2014-05-20  浏览次数:20957 次

内存溢出
下面的查询方法被调用几次(大概查询出1W-2W)后就会报java.lang.OutOfMemoryError: Java heap space
public List findUserInfoList(final int firstResult,final int maxResults){
return getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session s) throws HibernateException{
Criteria c = s.createCriteria(UserInfo.class);
c.setFirstResult(firstResult);
c.setMaxResults(maxResults);
return c.list();
}
});
}

这个查询方法是要用分页(5000/页)将UserInfo的所有数据查出来,UserInfo这个bean里面有一个对应的UserDetail,设置如下:
<one-to-one name="userDetail" class="com.laoer.bbscs.bean.UserDetail" lazy="no-proxy" cascade="all"/>
而UserDetail这个bean也有一个对应的UserInfo,设置如下:
<one-to-one name="userInfo" class="com.laoer.bbscs.bean.UserInfo" constrained="true"/>

UserInfo,UserDetail的属性都是用set、get方法

上面的方法被下面的方法调用
部分代码如下:
long num = total%5000==0 ? total/5000 : total/5000+1; //这里的num指的是能分多少页,total是总数量
List<UserInfo> listUI = new ArrayList<UserInfo>();
List<Note> listNotes = new ArrayList<Note>();
for(int i=0; i<num; ++i){
listUI = this.getUserService().findUserInfoList(i*5000, 5000);
for(int j=0;j<listUI.size();j++){
Note inboxNote = this.setNoteProperty(listUI.get(j));
listNotes.add(inboxNote);
}
this.getNoteService().batchSaveNotes(listNotes); //批量插入数据库
listNotes.clear(); //清空listNotes
listUI.clear(); //清空listUI
}

------解决方案--------------------
5000每页太多了,改成20每页

把5000个对象放在内存里,不一会内存溢出才怪
------解决方案--------------------
hiberante batch update 处理数据一次一般在20-100之间,5000太大了,怎么会超连接数呢,每次更新都建一个连接这个也有问题。
------解决方案--------------------
6楼的回答是正确的,每次更新都建一个连接这个也有问题
数据库多访问几次没有什么关系,只要配了数据库连接池就行了。
它最大的资源销耗是在创建connection.