December 2018
12.2k time
Why am I getting a stackoverflow error ?
My class —
The main method —
Error —
11 answers
Ваш метод ToString является виновником,
Потому что вы ссылаетесь this в ToString ()
Это означает , что this.toString() в настоящее время называется, для этого бесконечной рекурсии происходит
Поскольку использование первого это ваш метод ToString идет о вызове метода ToString рекурсивно приводит к StackOverflow.
и вы делаете , что из toString() , так toString() называют себя, которая называет себя, которая называет себя .
во время выполнения и будет снова звонить toString..wi вашего класса снова ..
В соответствии String rep = «Hex: » + this + «, Id: » + this.id;
и назвав его из ToString (), будет снова звонить ToString и снова .
равным String rep = «Hex: » + this.toString() + «, Id: » + this.id; внутренне
это будет приводит к рекурсивному вызову метода, который приведет к
В Java просто написание this означает , что вы косвенно , ссылающиеся this.toString() .
Я считаю , что вы пытаетесь переопределить toString() метод Object и внутри вашей версии toString() вы хотите напечатать идентификатор вы прошли вместе с hashcode объектом.
Таким образом, чтобы получить выход заменить
и вы получите выход, как:
Вы добавление «это». Это вызывает метод ToString (), который снова вызывает ToString (), . Это бесконечный цикл рекурсии, которая не имеет конца.
Я думаю, вы переопределение метода ToString и в вашей перекрытой тела вашего метода вызов метода еще раз! Вы звоните ToString написав это + «» в методе ToString
вы используете this ключевое слово.
Это представляет текущий объект. Ваш текущий объект вызывается снова и снова recursivley, так что вы получаете
I have a piece of code and I could not figure out why it is giving me Exception in thread «main» java.lang.StackOverflowError.
This is the question:
. I know the problem lies with the recursion. The error does not occur if the input is a small value, example: 5. But when the number is huge, like 90090249, I got the Exception in thread «main» java.lang.StackOverflowError. Thanks all for your help. 🙂
I almost forgot the error msg:
3 Answers 3
Your algorithm is fine. However int is too small for your computations, it fails for this input:
At some point integer overflows to negative value and your implementation goes crazy, recursing infinitely. Change int num to long num and you’ll be fine — for some time. Later you’ll need BigInteger .
Note that according to Wikipedia on Collatz conjecture (bold mine):
The longest progression for any initial starting number less than 100 million is 63,728,127, which has 949 steps. For starting numbers less than 1 billion it is 670,617,279, with 986 steps, and for numbers less than 10 billion it is 9,780,657,630, with 1132 steps.
The total number of steps is equivalent to maximum nesting level (stack depth) you can expect. So even for relatively big numbers StackOverflowError should not occur. Have a look at this implementation using BigInteger :
Что может вызвать java.lang.StackOverflowError ? Распечатка стека, которую я получаю, не очень глубока (всего 5 методов).
8 ответов
Что такое java.lang.StackOverflowError
Ошибка java.lang.StackOverflowError выводится, чтобы указать, что стек приложения был исчерпан из-за глубокой рекурсии, т. е. ваша программа / сценарий слишком сильно повторяется.
Подробности
StackOverflowError расширяет класс VirtualMachineError , который указывает на то, что JVM закончила или закончила работу и не может работать дальше. VirtualMachineError , который расширяет класс Error , используется для обозначения тех серьезных проблем, которые приложение не должно ловить. Метод не может объявлять такие ошибки в своем предложении throw , потому что эти ошибки являются ненормальными условиями, которые никогда не ожидались.
Пример
Minimal, Complete, and Verifiable Example :
Консольный выход
Объяснение
Когда вызов функции вызывается Java-приложением, стек стека выделяется в стеке вызовов. stack frame содержит параметры вызываемого метода, его локальные параметры и обратный адрес метода. Адрес возврата обозначает точку выполнения, из которой выполнение программы должно продолжаться после возврата вызванного метода. Если нет места для нового стека кадров, то StackOverflowError создается виртуальной машиной Java (JVM).
Наиболее распространенным случаем, который может вызывать стек Java-приложения, является рекурсия. В рекурсии метод запускается во время его выполнения. Recursion один из самых мощных методов программирования общего назначения, но его следует использовать с осторожностью, чтобы избежать StackOverflowError .
Ссылки
Когда вызов функции вызывается Java-приложением, стек стека выделяется в стеке вызовов. Фрейм стека содержит параметры вызываемого метода, его локальные параметры и обратный адрес метода.
Адрес возврата обозначает точку выполнения, из которой выполнение программы должно продолжаться после возврата вызванного метода. Если нет места для нового стека кадров, то StackOverflowError вызывается виртуальной машиной Java Virtual Machine (JVM) .
Наиболее распространенный случай который может исчерпать стек Java-приложения, является рекурсией.
Как решить StackOverflowError
В моем случае у меня есть два вида деятельности. Во втором упражнении я забыл поставить super на метод onCreate.
Исключения переполнения стека могут возникать, когда стек потоков продолжает расти в размере до достижения максимального предела.
Настройка параметров стека (Xss и Xmso) .
Одним из (необязательных) аргументов JVM является размер стека. Это -Xss. Я не знаю, что такое значение по умолчанию, но если общее количество вещей в стеке превышает это значение, вы получите эту ошибку.
Как правило, причиной является бесконечная рекурсия, но если вы видели это, ваша трассировка стека будет иметь более 5 кадров.
Попробуйте добавить аргумент -Xss (или увеличить значение одного), чтобы увидеть, не исчезло ли это.
Что фактически вызывает java.lang.StackOverflowError, как правило, является непреднамеренной рекурсией. Для меня часто бывает, когда я намеревался вызвать супер метод для метода overidden. Например, в этом случае:
Во-первых, полезно знать, что происходит за кулисами, когда мы вызываем функцию. Аргументы и адрес того, где был вызван метод, помещаются в стек (см. http://en.wikipedia.org/wiki/Stack_ (abstract_data_type) #Runtime_memory_management ), чтобы вызываемый метод мог доступа к аргументам и так, чтобы, когда вызываемый метод был завершен, выполнение может продолжаться после вызова. Но так как мы вызываем this.accelerate (ускорение, maxVelocity) рекурсивно (рекурсия отсутствует при вызове метода. Подробнее см. В http://en.wikipedia.org/wiki/Recursion_ (computer_science) ), мы находимся в ситуации, известной как бесконечная рекурсия, и мы продолжаем складывать аргументы и возвращать адрес в стеке вызовов. Поскольку стек вызовов конечен по размеру, мы в конечном итоге заканчиваем пространство. Запуск пространства в стеке вызовов называется переполнением. Это связано с тем, что мы пытаемся использовать больше пространства стека, чем у нас, и данные буквально переполняют стек. На языке программирования Java это приводит к исключению среды выполнения java.lang.StackOverflow и немедленно остановит программу.
Приведенный выше пример несколько упрощен (хотя это случается со мной больше, чем я хотел бы признать). То же самое может произойти в более круглом режиме, что затрудняет отслеживание. Однако, как правило, StackOverflow, как правило, довольно легко разрешать.
В теории также возможно переполнение стека без рекурсии, но на практике это выглядит как довольно редкий случай.