当前位置:编程学习 > JAVA >>

求助,内存溢出!

由于要做报表分析,需要把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相关
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,