Стратегия настройки сборки мусора Java - PullRequest
0 голосов
/ 17 марта 2019

У меня есть 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. В соответствии с некоторым if-тестом, я добавляю этот handInstanceP в новый LinkedList handInstanceListP или dealerHandInstanceList

в конце цикла handInstanceList. Я делаю следующее:

if (!handInstanceListP.isEmpty()) {
    return call(() -> setDealerHandsInstanceList(handInstanceListP, 
    dealerHandInstanceList));
} else {
    Thread.dumpStack();
    return TailCalls.done(dealerHandInstanceList);
}

Я уже пытался заглянуть в GC и настроить его параметры, но то, что я делаю, похоже, не работает.

При выполнении main я получаю OutOfMemoryErrors: 'java heapпробел »(когда я увеличил размер кучи до 2 ГБ) и« Превышен лимит накладных расходов ГХ »(когда я не установил никаких настроек, поэтому использую размеры и настройки по умолчанию) для самых требовательных запусков. Я работаю надWindows 10 с 8 ГБ оперативной памяти DDR4 (обратите внимание, что при запуске моей программы мне часто доступно только 4-5 ГБ)

Вопросы: Какой наиболее подходящий ГХ использовать? Параллельный ГХ, G1, последовательныйGC, UseConcMarkSweepGC?

Какие настройки GC мне нужно искать, в частности? Я думаю, есть много объектов, которые могутбыть назначенным только молодому поколению (см. объекты, объявленные сразу после оператора handInstanceList-loop-loop).(Например, у меня есть около 700 000 созданных int). Другие объекты являются более постоянными, как LinkedLists, но в основном это объекты в LinkList.Они созданы больше всего (около 8 миллионов раз и более на сложных пробегах).Я думаю, что они должны быть выделены старому поколению?Или можно сохранить их в молодом поколении и увеличить размер кучи молодого поколения?

Редактировать 1: я перешел на ArrayLists.

Редактировать 2: Действительно, это не реальноПроблема сбора мусора, больше попыток лениво обработать этот список в моей программе.Этот список существует только для целей расчета, как вы видите в конце цикла, я проверяю наличие пустого списка, поэтому в дальнейшем он мне не нужен.Мне нужно только изменить один конкретный объект, но для этого нужно много небольших изменений, и каждый цикл определяет одно небольшое изменение.

Если я использую потоки, у меня есть 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
});

Этот объект класса class2 лениво обрабатывается в моей программе, если он используется только и существует только в потоке forEach?

Другая возможность:

ArrayList<Class> list = new ArrayList<>();
Class class2 = new Class();
Stream stream = list.stream()
stream.forEach(class ->
{
   class2.add(class);
});

Возможно ли это сделать?Это похоже на глупый вопрос, но я действительно не привык к потокам, я не знаю, что возможно, а что нет.Но это может показаться странным, если последний пример невозможен.

...