Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我的Java应用程序内存不足_Java_Performance_Memory Management - Fatal编程技术网

我的Java应用程序内存不足

我的Java应用程序内存不足,java,performance,memory-management,Java,Performance,Memory Management,我的应用程序在使用大数据量执行操作时内存不足。数据是一个Java列表,大小约为100K个元素。 PersistData是实现该操作的类,PersistDataIntoDB是执行实际操作的类。由于操作耗时,调用PersistData的调用方会得到一个响应,表示操作已启动,并且有额外的API来获取操作的状态 另外,整个操作是并发的,并且该操作有多个调用者 下面是代码的样子(我希望它可读) 公共类持久化数据{ 公共布尔持久数据(列表数据记录){ //一些检查(较小的操作) 持久数据无差异线程(data

我的应用程序在使用大数据量执行操作时内存不足。数据是一个Java列表,大小约为100K个元素。
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;
    }
}