ArrayList内存不足错误

时间:2017-02-06 17:16:14

标签: java performance

我正在尝试从SQL数据库中检索100,000条记录,但在使用ArrayList时出现内存不足错误。

如何优化我的代码来实现这一目标?如何将flyweight设计模式应用于我的代码?

import java.math.BigDecimal;
import java.util.*;

public class Foo {
    public List<Vo> Service(Vo vo) throws Exception {
        HashMap<Integer, Object> param = null;
        ArrayList<HashMap<String, Object>> getRows = null;
        HashMap<String, Object> row = null;
        Vo Vo = null;

        try {
            List<Vo> list = new ArrayList<Vo>();

            if (Vo != null) {
                param = new HashMap();

                if (Vo.getCode() != null) {
                    param.put(1, Vo.getCode());
                    param.put(2, Vo.getCode());
                }
                if (Vo.getCode() != null) {
                    param.put(3, Vo.getCode());
                    param.put(4, Vo.getCode());
                }

                getRows = (ArrayList) ImpDAO.RetrieveQuery(param);

                if ((getRows != null) && (getRows.size() > 0)) {
                    for (Iterator iterator = getRows.iterator(); iterator.hasNext();) {
                        Vo = new Vo();
                        row = (HashMap) iterator.next();

                        if (row.get("CODE") != null)
                            Vo.setDept((BigDecimal) (row.get("CODE")));
                        if (row.get("SER") != null)
                            Vo.setServCode(row.get("SER").toString());
                        if (row.get("NAME") != null)
                            list.add(Vo);
                    }
                }
            }
        } catch (Exception ae) {
            throw ae;
        }

        return list;
    }
}

2 个答案:

答案 0 :(得分:0)

双数据结构

我看到的最大问题是(ArrayList)ImpDAO.RetrieveQuery(param):RetrieveQuery已经返回了一个哈希映射列表。因此,您的数据结构在内存中两次,但它们可能指向相同的对象。

考虑更改RetrieveQuery以返回由底层结果集支持的迭代器(或更好的流)。这将阻止您在内存中保留两个具有相同内容的大型数据结构。

对象类型

row.get("SER")的类型是什么?如果答案不是字符串,您可能会为每一行创建一个新字符串。这会大大增加你的内存占用。

row.get(&#34; CODE&#34;)怎么样?这需要是BigDecimal吗?一个int工作也一样吗?如果是这样,您可以通过切换在每行上保存几个字节。

100k是很多行

同时抓住100k行的原因很少。这是显示的ui吗?如果是这样,你真的会一次显示100k行吗?也许你应该看看分页。这是一个处理工作吗?也许我们可以设置限制并以块的形式处理它。

提出这样的问题会让人怀疑underlying problem是什么。

答案 1 :(得分:-1)

您可以尝试修改代码的以下部分,如下所示:

Iterator iterator = getRows.iterator();

while(iterator.hasNext()) {
                Vo=new Vo(); 
                row = (HashMap)iterator.next();
                if(row.get("CODE") != null )
                    Vo.setDept((BigDecimal) (row.get("CODE")));
                if(row.get("SER") != null )
                    Vo.setServCode(row.get("SER").toString());
                if(row.get("NAME") != null )

                list.add(Vo);
}