Что такое StackOverflowError?

407
задан Dan Fairaizl 7 January 2019 в 18:58
поделиться

6 ответов

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

Ваш процесс также имеет "куча" , который живет в нижняя часть конец Вашего процесса. Поскольку Вы выделяете память, эта "куча" может вырасти к верхнему концу Вашего адресного пространства. Как Вы видите, существует потенциал для "кучи" к [1 112], "сталкиваются" со стеком (немного как тектонические плиты!!!).

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

Однако с программированием GUI, возможно генерировать косвенная рекурсия . Например, Ваше приложение может обрабатывать сообщения краски, и, при обработке их, оно может вызвать функцию, которая заставляет систему отправлять другое сообщение краски. Здесь Вы явно не назвали себя, но OS/VM сделал это для Вас.

Для контакта с ними необходимо будет исследовать код. Если у Вас есть функции, которые называют себя, затем проверяют, что у Вас есть завершающееся условие. Если Вы будете иметь, то проверьте, что при вызывании функции Вы, по крайней мере, изменили один из аргументов, то иначе не будет никакого видимого изменения для рекурсивно вызванной функции, и завершающееся условие бесполезно. Также ум, что Ваше стековое пространство может исчерпать память прежде, чем достигнуть допустимого условия завершения, таким образом удостоверяется, что Ваш метод может обработать входные значения, требующие большего количества рекурсивных вызовов.

, Если у Вас нет очевидных рекурсивных функций затем, проверяют, чтобы видеть, называете ли Вы какие-либо библиотечные функции, которые косвенно заставят Вашу функцию быть названной (как неявный случай выше).

376
ответ дан Tom 8 January 2019 в 04:58
поделиться

Как Вы говорят, необходимо показать некоторый код. :-)

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

6
ответ дан Community 8 January 2019 в 04:58
поделиться

Переполнение стека обычно называют вложенные вызовы функции слишком глубоко (особенно легкий при использовании рекурсии, т.е. функции, которая называет себя) или выделение большого объема памяти на стеке, где использование "кучи" было бы более соответствующим.

8
ответ дан Greg 8 January 2019 в 04:58
поделиться

Переполнение стека означает точно что: переполнения стека. Обычно существует один стек в программе, которая содержит переменные локального объема и адреса, куда возвратиться, когда выполнение стандартной программы заканчивается. Тот стек имеет тенденцию быть диапазоном постоянной памяти где-нибудь в памяти, поэтому это ограничено, насколько это может содержать значения.

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

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

, Таким образом, переполнение стека появляется, где Вы выделяете слишком много в стек. Например, в упомянутой рекурсии.

Некоторые реализации оптимизируют некоторые формы рекурсий. Хвостовая рекурсия в частности. Рекурсивные стандартные программы хвоста являются формой стандартных программ, где рекурсивный вызов появляется как заключительная вещь, что делает стандартная программа. Такой стандартный вызов просто уменьшается в переход.

Некоторые реализации идут, насколько реализуют их собственные стеки для рекурсии, поэтому они позволяют рекурсии продолжаться, пока система не исчерпывает память.

Самая Легкая вещь, которую Вы могли попробовать, будет состоять в том, чтобы увеличить Ваш размер стека, если Вы можете. Если Вы не можете сделать этого, хотя, почти лучшая вещь состояла бы в том, чтобы посмотреть, существует ли что-то, что ясно вызывает переполнение стека. Попробуйте его путем печати чего-то прежде и после вызова в стандартную программу. Это помогает Вам узнать провальную стандартную программу.

24
ответ дан Cheery 8 January 2019 в 04:58
поделиться

Если у Вас есть функция как:

int foo()
{
    // more stuff
    foo();
}

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

62
ответ дан Khoth 8 January 2019 в 04:58
поделиться
  • 1
    Я don' t полагают Вам, что это работает в любом случае. Например, попытайтесь записать в файл PDF, сохраненный открытым Adobe Reader. – nalply 1 March 2013 в 02:09

Наиболее распространенная причина переполнений стека чрезмерно глубокая или бесконечная рекурсия . Если это - Ваша проблема, , это учебное руководство о Рекурсии Java могло бы помочь понять проблему.

5
ответ дан splattne 8 January 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: