求助,内存溢出!
由于要做报表分析,需要把sqlite数据库里的数据查出来组装一个Vector,可是由于数据量比较大(100W行,30列),在循环的时候总会内存溢出。但是如果不从数据库读取,直接循环加死值是没有问题的,内存占用大概350M,如果从数据库读取的话,内存会撑到2G以上,但是希望控制在1G以内,不知道怎么解决。求大神!
是要做cube报表分析(数据透视表),每次拖动都是在动态分析数据,因此得要所有数据。
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while(reader.next()) {
Vector<Object> lineData = new Vector<Object>();
int index=1;
//添加列数据
for (int i=0;i<htColums.size();i++) {
lineData.add(reader.getString(index++));
//lineData.add("啦啦啦啦啦啦拉拉拉拉啊啊阿拉拉拉阿拉");
}
//添加计算数据
for (Object key : htDatas.keySet()) {
if(index>=colums.length){break;}
float f=reader.getFloat(index++);
//Float value=123.01F;
lineData.add(f);
}
data.add(lineData);
lineData=null;
}
内存溢出
报表
内存
--------------------编程问答--------------------
如果木有修改集合里面的没必要用vector,用list或者hashmap..你预估下数据量的大小,然后new容器的时候不要能再使用默认值拉...不然扩容浪费资源太多...如果一个装不下new多几个容器去装,然后再把这些小容器装在一个大的容器里,例如,List<List<?>> 或者是Map<Key,List<?>>等等...仅供参考...
--------------------编程问答--------------------
两点建议吧:
1. 只取关键列,减少每条数据的数据量
2. 报表以增量形式实现。例如:10W条的报表结果图,然后再来10W条,在原来结果基础上对报表的影响计算出来体现以下。(这样的效果可能是,你的报表不会突然变成一个数据,而是有个渐变的过程,达到最后的结果)
--------------------编程问答--------------------
从数据库读取和直接循环加死值应该是没有多大区别的,
创建Statement加两个参数试一下
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWORD_ONLY, ResultSet.CONCUR_READ_ONLY);
另外两个for循环可以修改一下,htColums.size()和for (Object key : htDatas.keySet())仅仅只是控制循环次数,可以先把次数计算出来不要在循环里重复计算。
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
int columnsLeight = htColums.size();
while (reader.next()) {
Vector<Object> lineData = new Vector<Object>(colums.length);
int index = 0;
while (index < colums.length) {
if (index++ < columnsLeight)
lineData.add(reader.getString(index));
else lineData.add(reader.getFloat(index));
}
data.add(lineData);
}
--------------------编程问答--------------------
引用 3 楼 bree06 的回复: 从数据库读取和直接循环加死值应该是没有多大区别的,
创建Statement加两个参数试一下
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWORD_ONLY, ResultSet.CONCUR_READ_ONLY);
另外两个for循环可以修改一下,htColums.size()和for (Object key : htDatas.keySet())仅仅只是控制循环次数,可以先把次数计算出来不要在循环里重复计算。
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
int columnsLeight = htColums.size();
while (reader.next()) {
Vector<Object> lineData = new Vector<Object>(colums.length);
int index = 0;
while (index < colums.length) {
if (index++ < columnsLeight)
lineData.add(reader.getString(index));
else lineData.add(reader.getFloat(index));
}
data.add(lineData);
}
谢谢的你方法,效率确实有所提高,但是效果还不是很理想,也是需要耗费超过1.5G内存才可以把循环走完。
引用 2 楼 oh_Maxy 的回复: 两点建议吧:
1. 只取关键列,减少每条数据的数据量
2. 报表以增量形式实现。例如:10W条的报表结果图,然后再来10W条,在原来结果基础上对报表的影响计算出来体现以下。(这样的效果可能是,你的报表不会突然变成一个数据,而是有个渐变的过程,达到最后的结果)
也谢谢你的回复,由于使用哪些列是客户自己来确定的,因此我们得把所有列都放出来,以供客户去触发显示出来。
引用 1 楼 shadowsick 的回复: 如果木有修改集合里面的没必要用vector,用list或者hashmap..你预估下数据量的大小,然后new容器的时候不要能再使用默认值拉...不然扩容浪费资源太多...如果一个装不下new多几个容器去装,然后再把这些小容器装在一个大的容器里,例如,List<List<?>> 或者是Map<Key,List<?>>等等...仅供参考...
由于java swing的TableModel需要的数据源就是vector或者object二维数组,所以不能换成list,且ArrayList占用的内存也不逊于用vector
--------------------编程问答--------------------
引用 4 楼 gap12521 的回复: Quote: 引用 3 楼 bree06 的回复:
从数据库读取和直接循环加死值应该是没有多大区别的,
创建Statement加两个参数试一下
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWORD_ONLY, ResultSet.CONCUR_READ_ONLY);
另外两个for循环可以修改一下,htColums.size()和for (Object key : htDatas.keySet())仅仅只是控制循环次数,可以先把次数计算出来不要在循环里重复计算。
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
int columnsLeight = htColums.size();
while (reader.next()) {
Vector<Object> lineData = new Vector<Object>(colums.length);
int index = 0;
while (index < colums.length) {
if (index++ < columnsLeight)
lineData.add(reader.getString(index));
else lineData.add(reader.getFloat(index));
}
data.add(lineData);
}
谢谢的你方法,效率确实有所提高,但是效果还不是很理想,也是需要耗费超过1.5G内存才可以把循环走完。
引用 2 楼 oh_Maxy 的回复: 两点建议吧:
1. 只取关键列,减少每条数据的数据量
2. 报表以增量形式实现。例如:10W条的报表结果图,然后再来10W条,在原来结果基础上对报表的影响计算出来体现以下。(这样的效果可能是,你的报表不会突然变成一个数据,而是有个渐变的过程,达到最后的结果)
也谢谢你的回复,由于使用哪些列是客户自己来确定的,因此我们得把所有列都放出来,以供客户去触发显示出来。
引用 1 楼 shadowsick 的回复: 如果木有修改集合里面的没必要用vector,用list或者hashmap..你预估下数据量的大小,然后new容器的时候不要能再使用默认值拉...不然扩容浪费资源太多...如果一个装不下new多几个容器去装,然后再把这些小容器装在一个大的容器里,例如,List<List<?>> 或者是Map<Key,List<?>>等等...仅供参考...
由于java swing的TableModel需要的数据源就是vector或者object二维数组,所以不能换成list,且ArrayList占用的内存也不逊于用vector
换了这个不是占不占内存的问题,而是大容量的数据,vector是强制同步的,访问效率不行
补充: Java , Java相关