Каждый вызов рекурсивной функции занимает место в стеке потока. В Java Arrays.sort(Object[] a) использует сортировку слиянием. Сортировка слиянием с использованием рекурсивного вызова функции. Почему мы не получаем StackOverflowError для большого массива-списка?

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

1
Akashsingla19 8 Июл 2015 в 18:00
3
Потому что журнал (база 2) 2147483647 составляет около 31, и это действительно не так уж глубоко?
 – 
azurefrog
8 Июл 2015 в 18:07
Переполнение стека (которое составляет Error) вызывается JVM при переполнении стека. Вы, скорее всего, превысите кучу со слишком большим массивом.
 – 
Mena
8 Июл 2015 в 18:08

2 ответа

Arrays.sort использует не классическую версию сортировки слиянием из учебника, а гораздо более сложную версию, основанную на TimSort как вы можете прочитать здесь.

Кроме того, в Java размер стека не является фиксированным пределом, а может быть задан как опция JVM.

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

0
Diego Martinoia 8 Июл 2015 в 18:08
Я видел реализацию Arrays.sort(Object[] a) по этой ссылке: grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/ …
 – 
Akashsingla19
8 Июл 2015 в 19:39
Ваша ссылка исходит, я думаю, из Java6. Обновленный код:
 – 
Diego Martinoia
9 Июл 2015 в 11:47
1
Public static void sort(Object[] var0) { if(Arrays.LegacyMergeSort.userRequested) { legacyMergeSort(var0); } else { ComparableTimSort.sort(var0, 0, var0.length, (Object[])null, 0, 0); } }
 – 
Diego Martinoia
9 Июл 2015 в 11:47

Типичный стек Java имеет размер не менее 64 КБ. Поскольку идея сортировки слиянием состоит в том, чтобы разбивать массив на 2 на каждом шаге, вам потребуется как минимум, скажем, 3000 разбиений, чтобы получить переполнение стека. Скажем, у вас есть массив объектов размером 32 бита (т.е. примерно 4 миллиарда) элементов, который все еще НАМНОГО меньше 64k. Таким образом, Arrays.sort не подвержен переполнению стека.

0
ControlAltDel 8 Июл 2015 в 18:09