我的Java应用程序内存不足

时间:2015-12-12 07:25:05

标签: java performance memory-management

我的应用程序在执行大数据操作时内存不足。数据是Java List,大小约为100K元素。 PersistData是实现操作的类,PersistDataIntoDB是执行实际操作的类。由于操作耗时,PersistData的调用者会得到一个响应,说明操作已经开始,并且还有其他API来获取操作的状态。

此外,整个操作并发,并且有多个调用者进行操作。

这是代码的样子(我希望它的可读性)。

public class PersistData {
    public Boolean persistData(List<ClassA> dataRecs) {
        //some checks (smaller operation)
        persistDataInDifferentThread(dataRecs);
        //if no errors in checks return true
        return true;
    }

    private void persistDataInDifferentThread(List<ClassA> dataRecs) {
        Thread runnerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    List convertedList = constructClassBUsingClassA(dataRecs);
                    PersistDataIntoDB dbPersist = new PersistDataIntoDB();
                    dbPersist.persistDataInDB(convertedList);
                }
                catch (Exception e) {
                }
            }
        });
    }

     private List<ClassB> constructClassBUsingClassA(List<ClassA> dataRecs) {
    List<ClassB> tempList = new ArrayList<ClassB>();
    for (int i = 0; i < dataRecs.size(); i++) {
        ClassA tempRec = dataRecs.get(i);
        ClassB tempRecB = new ClassB();
        //put stuff from tempRec to tempRecB
        tempList.add(tempRecB);
    }
    return tempList;
}

}

执行持久性的类。

public class PersistDataIntoDB {
     public Boolean persistDataInDB(List<ClassB> dataRecs){
        //if all goes well return true
        return true;
    }
}

我的问题是我的方法persistDataInDifferentThread是否可以重构?因为在它运行时,内存中有两个大的列表,对persistDataInDB的调用需要很长时间才能完成,垃圾收集器可能会即使我在调用List<ClassA>之后不需要它,也不会卸载persistDataInDB

我的上述分析是错误的吗?我只需要增加最大堆,因为我正在处理大数据?

1 个答案:

答案 0 :(得分:2)

  

我的上述分析是错误的吗?我只需要增加最大堆,因为我正在处理大数据?

是的,是的。

1)使用多个线程不会增加或减少使用的堆空间量。

2)如果堆填满,那么JVM会在投掷OOME之前尽力回收空间。

唯一可能产生影响的是,如果一个线程创建了列表并将其传递给第二个实例以进行持久化......并且还挂起到列表的引用。这可能导致列表保持可访问的时间超过其需要的时间。

如果你有多个跑步者线程持久存在多个列表,我猜你也会遇到麻烦,而且工作的到达时间比你处理它的速度快。如果这是问题所在,那么您需要做一些事情来控制接受请求的速率。