我的应用程序在执行大数据操作时内存不足。数据是一个 Java 列表,大小约为 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
后不需要它.
我上面的分析有错吗?我只需要增加最大堆,因为我正在处理大数据?
最佳答案
Is my above analysis wrong? I just have to increase the max heap because I am dealing with large data?
是的,是的。
1) 使用多线程不会增加或减少堆空间的使用量。
2) 如果堆已满,那么 JVM 将在抛出 OOME 之前尽一切努力回收空间。
唯一可能产生影响的是一个线程是否创建列表并将其传递给第二个实例以进行持久化......并且还挂起对该列表的引用。这可能会导致列表保持可达状态的时间超过其需要的时间。
我猜如果您有多个运行程序线程保存多个列表,并且工作到达的速度比您处理它的速度快,您也可能会遇到麻烦。如果这就是问题所在,那么您需要采取一些措施来控制接受请求的速率。
关于java - 我的 Java 应用程序内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34237409/