Ошибка при слиянии OutOfMemoryError

#java #sorting #mergesort

#java #сортировка #сортировка слиянием

Вопрос:

Я пытаюсь реализовать рекурсивный алгоритм сортировки слиянием для сортировки массива, но я продолжаю сталкиваться с этой проблемой в части слияния, и я не понимаю, почему я получаю эту ошибку:

Исключение в потоке «main» java.lang.Ошибка OutOfMemoryError: пространство кучи Java Помечает ошибку в строке 21

Вот код только для части слияния, рекурсивная часть, похоже, не имеет проблем

 public static void Intercala(ArrayList<Alumno> L, int ini, int mitad, int fin){
    int i=ini;
    int j= mitad 1;
    int k = ini;
    ArrayList<Alumno> B = new ArrayList <Alumno>();

    while(i<=mitad amp;amp; j<=fin){
        if (L.get(i).get_matri() <= L.get(j).get_matri()){
            B.add(k,L.get(i));
            i  ;
        }
        else{
            B.add(k,L.get(j));
            j  ;
        }
        k  ;

    }
    if (i>mitad){
        for(int h=j; h<=fin; k  ){
            B.add(k,L.get(h));
        }
            k  ;
    }
    else{
        for (int h=i; h<=mitad;k  ){
            B.add(k,L.get(h));
        }
        k  ;
    }
    for(i=ini; i<=fin; i  ){
        L.set(i, B.get(i));
    }
}
  

Кто-нибудь может мне помочь? Я уже пытался перепроверить код, но, похоже, ничего не помогает

РЕДАКТИРОВАТЬ: уже пытался расширить память и все еще выдает эту ошибку

Комментарии:

1. По сути, у вас закончилась память для создания новых объектов. Строка 21 создала объект, который сломал спину верблюду.

2. B.add(k,L.get(h)); является медленной операцией над списком массивов, если k не приближается к концу.

3. Рекурсивные алгоритмы требуют много памяти. Как насчет изменения максимального размера кучи путем добавления параметра -Xmx.

Ответ №1:

Глядя на код, я не вижу ничего плохого в логике. Единственный вывод, к которому я могу прийти, — это то, как ArrayList распределяет память. Размер по умолчанию равен 10, и когда вы достигнете предела, вы удвоите выделяемую память. Он продолжает это делать.

Проблема также может заключаться в том, сколько памяти занимает объект Alumno. При таком взрывном распределении памяти из ArrayList возможно исчерпание пространства. Если вы хотите использовать List, я предлагаю использовать LinkedList, где размер автоматически не удваивается при достижении емкости.

Может быть проблема с вашей функцией рекурсии, но я предполагаю, что это правильно.

Надеюсь, это поможет!

Ответ №2:

После цикла while.

 if (i>mitad){
    for(int h=j; h<=fin; k  ){
        B.add(k,L.get(h));
    }
        k  ;
}
else{
    for (int h=i; h<=mitad;k  ){
        B.add(k,L.get(h));
    }
    k  ;
}
  

Эти 2 цикла for будут выполняться бесконечно.

Потому что h не изменится в цикле.