我有一个处理大量数据的Java应用程序。
占用所有内存的方法如下:
这是一个尾部递归方法(我使用蹦床使栈安全),该方法首先通过LinkedList(可以包含很多对象,最多几百万个对象)进行迭代,对于每个对象,我经历另一个int = 1到13的循环。
private TailCall<LinkedList<HandInstance>>
setDealerHandsInstanceList(LinkedList<HandInstance> handInstanceList,
LinkedList<HandInstance> dealerHandInstanceList) {
final LinkedList<HandInstance> handInstanceListP = new LinkedList<>();
for (HandInstance handInstance : handInstanceList) {
Shoe shoe = handInstance.getShoe();
BigDecimal kansAlGespeeldeKaarten = handInstance.getKansAlGespeeldeKaarten();
int spelerTotaalInitiaal = handInstance.getSpelerTotaalInitiaal();
for (Kaart kaart : shoe.getDefaultHand()) {
//(--> defaultHand contains 13 elements)
在defaultHand循环中,我创建了一个新的handInstanceP,对初始handInstance的属性进行了深度复制,并将它们设置为新的handInstanceP。 (同时根据defaultHand-loop更改这些属性。 根据一些if测试,我将此handInstanceP添加到新的LinkedList handInstanceListP或DealerHandInstanceList
在handInstanceList循环的结尾,我执行以下操作:
if (!handInstanceListP.isEmpty()) {
return call(() -> setDealerHandsInstanceList(handInstanceListP,
dealerHandInstanceList));
} else {
Thread.dumpStack();
return TailCalls.done(dealerHandInstanceList);
}
我已经尝试研究GC并调整其设置。但是我做的似乎无效。
执行主程序时,出现OutOfMemoryErrors:“ java堆空间”(当我将堆大小增加到总计2gb时)和“超出了GC开销限制”(当我未进行任何设置时,因此使用默认值)尺寸和设置)。 我在Windows 10上运行,带有8GB DDR4内存RAM(请注意,启动程序时我通常只有4-5GB的可用空间)
问题: 使用哪种更合适的GC?并行GC,G1,串行GC,UseConcMarkSweepGC?
我特别需要寻找哪些GC设置?我猜有很多对象只能分配给Young Generation(请参阅在handInstanceList-loop-statement之后声明的对象)。 (例如,我有大约700.000 int被创建) 其他对象是更永久的,例如LinkedLists,但主要是linkedList中的对象。这些被创建最多(大约800万次,并且在苛刻的运行中更多)。我猜这些应该分配给老一代吗?还是可以将它们保留在Young Generation中并增加Young Gen堆大小?
编辑1:我已更改为ArrayLists。
编辑2:确实,这不是垃圾回收的真正问题,更多的是尝试在我的程序中延迟处理此列表。该列表仅出于计算原因而存在,就像您在循环结束时看到的那样,我检查一个空列表,因此以后不需要该列表。我只需要它来更改一个特定的对象,但是它需要很多小的更改,并且每个循环都定义一个小的更改。
如果我使用流,则有两个问题。 如果我有以下内容:
ArrayList<Class> list = new ArrayList<>();
Stream stream = list.stream()
stream.forEach(class ->
{
Class class2 = new Class();
class2.add(class);
// other things done with class2
});
如果仅使用并且仅存在于forEach-stream中,则该Class class2对象是否在我的程序中被延迟处理?
另一种可能性:
ArrayList<Class> list = new ArrayList<>();
Class class2 = new Class();
Stream stream = list.stream()
stream.forEach(class ->
{
class2.add(class);
});
这有可能吗?它看起来像一个愚蠢的问题,但是我真的不习惯流媒体,我不知道有什么可能,什么没有。但是,如果没有最后一个例子,这似乎很奇怪。