我的Java应用程序内存不足
我的应用程序在使用大数据量执行操作时内存不足。数据是一个Java列表,大小约为100K个元素。我的Java应用程序内存不足,java,performance,memory-management,Java,Performance,Memory Management,我的应用程序在使用大数据量执行操作时内存不足。数据是一个Java列表,大小约为100K个元素。 PersistData是实现该操作的类,PersistDataIntoDB是执行实际操作的类。由于操作耗时,调用PersistData的调用方会得到一个响应,表示操作已启动,并且有额外的API来获取操作的状态 另外,整个操作是并发的,并且该操作有多个调用者 下面是代码的样子(我希望它可读) 公共类持久化数据{ 公共布尔持久数据(列表数据记录){ //一些检查(较小的操作) 持久数据无差异线程(data
PersistData
是实现该操作的类,PersistDataIntoDB
是执行实际操作的类。由于操作耗时,调用PersistData
的调用方会得到一个响应,表示操作已启动,并且有额外的API来获取操作的状态
另外,整个操作是并发的,并且该操作有多个调用者
下面是代码的样子(我希望它可读)
公共类持久化数据{
公共布尔持久数据(列表数据记录){
//一些检查(较小的操作)
持久数据无差异线程(dataRecs);
//如果检查中没有错误,则返回true
返回true;
}
私有void persistDataInDifferentThread(列出DataRec){
线程runnerThread=新线程(new Runnable(){
公开募捐{
试一试{
List convertedList=ConstructionClassBusingClassA(dataRecs);
PersistDataIntoDB dbPersist=新的PersistDataIntoDB();
dbPersist.persistDataInDB(convertedList);
}
捕获(例外e){
}
}
});
}
私有列表构造ClassBusingClassA(列表数据记录){
List templast=new ArrayList();
对于(int i=0;i
类,该类执行持久性
public class PersistDataIntoDB {
public Boolean persistDataInDB(List<ClassB> dataRecs){
//if all goes well return true
return true;
}
}
公共类PersistDataIntoDB{
公共布尔persistDataInDB(列出DataRec){
//如果一切顺利,结果会是真的
返回true;
}
}
我的问题是我的方法persistDataInDifferentThread
是否可以重构?因为当它运行时,内存中有两个大列表,对persistDataInDB
的调用需要很长时间才能完成,垃圾收集器可能不会卸载列表
,即使调用persistDataInDB
后我不需要它
我的上述分析是错误的吗?我只需要增加最大堆,因为我处理的是大数据
我的上述分析是错误的吗?我只需要增加最大堆,因为我处理的是大数据
对,对
1) 使用多个线程不会增加或减少所使用的堆空间量
2) 如果堆已满,JVM将在抛出OOME之前尽一切努力回收空间
唯一不同的是,如果一个线程创建列表并将其传递给第二个实例进行持久化。。。并挂起对列表的引用。这可能会导致列表保持可访问状态的时间比需要的时间长
我想如果您有多个运行线程保存多个列表,并且工作到达的速度快于您处理它的速度,您也可能会遇到麻烦。如果这就是问题所在,那么您需要采取一些措施来控制接受请求的速率。从您提供的内容很难判断,当前实现的一个明显问题是,对将启动的persistData重复调用的线程数没有限制。频繁地调用它,很容易耗尽资源。您可能想考虑队列和用户或线程池的方法。您能演示如何设置列表/列表中的内容吗?您是否需要为每个列表创建持久性DATABDB数据库?这似乎是一个带有静态方法的类。@Jan列表包含我的一个数据结构的元素。ClassA的数据结构与ClassB略有不同,因此,我为ClassA的每个对象构造了ClassB的对象,其中有调用者提供的列表。您能显示ConstructionClassBusingClassA的完整代码吗?不清楚你是如何将一个类转换成另一个类的?谢谢。我尚未确认“挂起对列表的引用”部分我的理解是@
dbPersist.persistDataInDB(convertedList)代码>,两个列表(ClassA和ClassB的列表)在内存中。但是我不需要ClassB的列表,因为我已经处理了它。对吗?@dRV持久化列表将在persistDataInDifferentThread完成后从内存中删除,因为应用程序丢失了到此列表的链接。一旦创建了ClassB列表,就不需要保留对ClassA列表的引用。(如果您已经这样做了,那么您将增加堆的使用率……但解决方案是“不要”。)
public class PersistDataIntoDB {
public Boolean persistDataInDB(List<ClassB> dataRecs){
//if all goes well return true
return true;
}
}