Stackoverflowerror java что это
Что вызывает java.lang.StackOverflowError
ОТВЕТЫ
Ответ 1
Проверить любые призывы к использованию методов. В основном это вызвано, когда существует рекурсивный вызов метода. Простой пример:
Здесь System.out.println(i); будет многократно вытолкнут в стек при вызове метода testMethod.
Ответ 2
Как правило, причиной является бесконечная рекурсия, но если вы это видите, ваша трассировка стека будет иметь более 5 кадров.
Ответ 3
Что на самом деле вызывает 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 обычно легко разрешается, как только это происходит.
В теории также возможно переполнение стека без рекурсии, но на практике это будет довольно редкое событие.
Ответ 4
Что такое java.lang.StackOverflowError
подробности
Пример
Minimal, Complete, and Verifiable Example :
Консольный выход
Explaination
Когда вызов функции вызывается приложением Java, в стеке вызовов выделяется кадр стека. stack frame содержит параметры вызванного метода, его локальные параметры и адрес возврата метода. Адрес возврата обозначает точку выполнения, с которой выполнение программы должно продолжаться после возврата вызванного метода. Если для нового фрейма стека нет места, StackOverflowError виртуальной машиной Java (JVM).
Рекомендации
Ответ 5
Когда вызов функции вызывается Java-приложением, стек стека выделяется в стеке вызовов. Фрейм стека содержит параметры вызываемого метода, его локальные параметры и обратный адрес метода.
Обратный адрес обозначает точку выполнения, из которой выполнение программы должно продолжаться после возврата вызванного метода. Если места для нового стека нет, то StackOverflowError вызывается виртуальной машиной Java (JVM).
Наиболее распространенным случаем, который может исчерпать стек приложений Java, является рекурсия.
Как решить StackOverflowError
Ответ 6
Я создал программу с hibernate, в которой я создал два класса POJO, как с объектом друг друга, так и с элементами данных. Когда в основном методе я попытался сохранить их в базе данных, я также получил эту ошибку.
Это происходит потому, что оба класса ссылаются друг на друга, поэтому создается цикл, который вызывает эту ошибку.
Итак, проверьте, существуют ли какие-либо подобные отношения в вашей программе.
Ответ 7
Исключения могут возникать, когда стек потоков продолжает расти в размере до достижения максимального предела.
Настройка параметров стека (Xss и Xmso).
Предлагаю вам посмотреть эту ссылку: http://www-01.ibm.com/support/docview.wss?uid=swg21162896 Существует много возможных причин для StackOverflowError, как вы можете видеть в ссылке.
Ответ 8
Попробуйте очистить проект перед компиляцией
при компиляции и при внезапной сбое памяти это может вызвать эту ошибку.
Ответ 9
В моем случае у меня есть два вида деятельности. Во втором упражнении я забыл поставить super на метод onCreate.
Ответ 10
Решение для пользователей Hibernate при разборе данных:
У меня была эта ошибка, потому что я анализировал список объектов, отображенных с обеих сторон @OneToMany и @ManyToOne в json, используя Джексона, что вызвало бесконечный цикл.
Определения из API:
Owner.java:
Car.java:
Другое решение состоит в том, чтобы использовать @JsonIgnore который просто установит нулевое значение в поле.
Ошибка StackOverflowError в Java
Узнайте, как происходит одна из наиболее распространенных ошибок Java – StackOverflowError – и как ее устранить.
1. Обзор
StackOverflowError может раздражать разработчиков Java, так как это одна из самых распространенных ошибок во время выполнения, с которой мы можем столкнуться.
В этой статье мы рассмотрим, как может возникнуть эта ошибка, рассмотрев различные примеры кода, а также то, как мы можем с ней справиться.
2. Кадры стека и как происходит ошибка StackOverflowError
Давайте начнем с основ. При вызове метода в стеке вызовов создается новый кадр стека. Этот кадр стека содержит параметры вызываемого метода, его локальные переменные и адрес возврата метода, т. е. точку, из которой выполнение метода должно продолжаться после возврата вызванного метода.
Создание фреймов стека будет продолжаться до тех пор, пока не будет достигнут конец вызовов методов, найденных внутри вложенных методов.
Наиболее распространенной причиной, по которой JVM сталкивается с этой ситуацией, является unterminated/бесконечная рекурсия – в описании Javadoc для StackOverflowError упоминается, что ошибка возникает в результате слишком глубокой рекурсии в конкретном фрагменте кода.
В следующем разделе мы рассмотрим некоторые примеры кода, демонстрирующие эти сценарии.
3. Ошибка StackOverflowError в действии
В примере, показанном ниже, StackOverflowError будет вызван из-за непреднамеренной рекурсии, когда разработчик забыл указать условие завершения для рекурсивного поведения:
Здесь ошибка возникает во всех случаях для любого значения, переданного в метод:
Этот набор тестов демонстрирует этот сценарий:
В данном конкретном случае ошибки можно было бы полностью избежать, если бы условие завершения было просто сформулировано как:
Вот тест, который показывает этот сценарий на практике:
Далее мы рассмотрим, что происходит, когда экземпляр класса создается в том же классе, что и переменная экземпляра этого класса.
Как видно из следующего примера, Владелец счета создает экземпляр в качестве переменной экземпляра Владелец совместного счета :
Когда Владелец учетной записи класс создается , a StackOverflowError выбрасывается из-за рекурсивного вызова конструктора, как показано в этом тесте:
4. Работа С Ошибкой StackOverflowError
Лучшее, что можно сделать при обнаружении || StackOverflowError||, – это осторожно проверить трассировку стека, чтобы определить повторяющийся шаблон номеров строк. Это позволит нам найти код, который имеет проблемную рекурсию.
Здесь можно увидеть повторение строки № 5. Именно здесь выполняется рекурсивный вызов. Теперь это просто вопрос изучения кода, чтобы увидеть, правильно ли выполняется рекурсия.
Вот трассировка стека, которую мы получаем, выполняя ручной тест циклической зависимости (опять же, без ожидаемого исключения):
Эта трассировка стека показывает номера строк, которые вызывают проблему в двух классах, находящихся в циклической связи. Строка номер 9 класса Два и строка номер 9 класса Один указывают на местоположение внутри конструктора, где он пытается создать экземпляр другого класса.
После тщательной проверки кода и если ни одно из следующих действий (или любая другая логическая ошибка кода) не является причиной ошибки:
Было бы неплохо попытаться увеличить размер стека. В зависимости от установленной JVM размер стека по умолчанию может варьироваться.
Флаг -Xss можно использовать для увеличения размера стека либо из конфигурации проекта, либо из командной строки.
5. Заключение
Что такое StackOverflowError?
13 ответов
параметры и локальные переменные выделяется на стек (со ссылочными типами объект живет на кучу и переменная ссылается на этот объект). Стек обычно живет в верхний конец вашего адресного пространства и по мере его использования он направляется к дно адресного пространства (т. е. к нулю).
ваш процесс также имеет кучу, который живет в дно конце процесс. По мере выделения памяти эта куча может расти к верхнему концу адресного пространства. Как вы можете видеть, существует потенциал для кучи «наехать» со стеком (немного похоже на тектонические плиты. ).
общей причиной переполнения стека является плохой рекурсивный вызов. Как правило, это вызвано тем, что рекурсивные функции не имеют правильного условия завершения, поэтому он вызывает себя навсегда.
однако, с GUI программирование, можно генерировать косвенная рекурсия. Например, приложение может обрабатывать сообщения paint и при их обработке вызывать функцию, которая заставляет систему отправлять другое сообщение paint. Здесь вы явно не вызывали себя, но OS / VM сделала это за вас.
чтобы справиться с ними, вам нужно будет изучить свой код. Если у вас есть функции, которые называют себя, проверьте, что у вас есть условие завершения. Если да, то проверьте, что при вызове функции вы хотя бы изменили один из аргументов, иначе не будет видимых изменений для рекурсивно вызываемой функции, и условие завершения бесполезно.
Если у вас нет очевидных рекурсивных функций, проверьте, вызываете ли вы какие-либо библиотечные функции, которые косвенно вызовет вызов вашей функции (например, неявный случай выше).
чтобы описать это, сначала давайте поймем, как местные переменные и объекты.
локальные переменные хранятся в стек:
если вы посмотрите на изображение, вы должны быть в состоянии понять, как вещи работают.
когда вызов функции вызывается приложением Java, в стеке вызовов выделяется кадр стека. Фрейм стека содержит параметры вызываемого метода, его локальный параметры и обратный адрес метода. Обратный адрес обозначает точку выполнения, с которой выполнение программы должно продолжаться после возвращения вызванного метода. Если нет места для нового кадра стека, то StackOverflowError выбрасывается виртуальной машиной Java (JVM).
пример кидания StackOverflowError показано ниже:
StackOverflowErrorExample.java:
в этом примере мы определяем рекурсивный метод, называемый recursivePrint который печатает целое число, а затем вызывает себя со следующим последовательным целым числом в качестве аргумента. Рекурсия заканчивается, пока мы не перейдем в 0 в качестве параметра. Однако, в нашем примере, мы передали параметр из 1 и его возрастающих последователей, следовательно, рекурсия никогда не закончится.
в зависимости от начальной конфигурации JVM результаты могут отличаться, но в конечном итоге StackOverflowError будет брошено. Этот пример является очень хорошим примером того, как рекурсия может вызвать проблемы, если не реализованы осторожность.
как бороться с StackOverflowError
самое простое решение-тщательно проверить трассировку стека и обнаружьте повторяющийся шаблон номеров строк. Эти номера строк укажите код, вызываемый рекурсивно. Как только вы обнаружите это строки, вы должны тщательно проверить свой код и понять, почему рекурсия никогда не заканчивается.
Если у вас есть функция как:
тогда foo () будет продолжать вызывать себя, все глубже и глубже, и когда пространство, используемое для отслеживания того, какие функции вы используете, заполняется, вы получаете ошибку переполнения стека.
переполнение стека означает именно это: переполнение стека. Обычно в программе есть один стек, который содержит переменные локальной области и адреса, куда возвращаться при завершении выполнения подпрограммы. Этот стек имеет тенденцию быть фиксированным диапазоном памяти где-то в памяти, поэтому он ограничен тем, сколько он может содержать значения.
Если стек пуст, вы не можете поп, если вы это сделаете, вы получите ошибку стека underflow.
Если стек заполнен, вы не можете нажать, если вы это сделаете вы получите ошибку переполнения стека.
таким образом, переполнение стека появляется там, где вы выделяете слишком много в стек. Например, в упомянутой рекурсии.
некоторые реализации оптимизируют некоторые формы рекурсий. В частности, хвостовая рекурсия. Хвост рекурсивные подпрограммы-это форма подпрограмм, где рекурсивный вызов появляется как последнее, что делает подпрограмма. Такой рутинный вызов просто сводится к прыжку.
некоторые реализации заходят так далеко, что реализуют их собственные стеки для рекурсии, поэтому они позволяют рекурсии продолжаться до тех пор, пока в системе не закончится память.
самое простое, что вы могли бы попробовать, это увеличить размер стека, если сможете. Если вы не можете этого сделать, второе, что лучше всего было бы посмотреть, есть ли что-то, что явно вызывает переполнение стека. Попробуйте, распечатав что-то до и после вызова в рутину. Это поможет вам выяснить, что происходит.
переполнение стека обычно вызывается слишком глубокими вызовами функции вложенности (особенно легко при использовании рекурсии, т. е. функции, которая вызывает себя) или выделением большого объема памяти в стеке, где использование кучи было бы более уместным.
Как вы говорите, вам нужно показать какой-то код. 🙂
ошибка переполнения стека обычно происходит, когда ваша функция вызывает nest слишком глубоко. Вижу Код Переполнения Стека Golf поток для некоторых примеров того, как это происходит (хотя в случае этого вопроса ответы намеренно вызывают переполнение стека).
наиболее распространенной причиной переполнения стека является чрезмерно глубокая или бесконечная рекурсия. Если это ваша проблема, этот учебник о рекурсии Java может помочь понять проблему.
StackOverflowError находится в стеке, как OutOfMemoryError находится в куче.
неограниченные рекурсивные вызовы приводят к использованию пространства стека.
следующий пример производит StackOverflowError :
StackOverflowError можно избежать, если рекурсивные вызовы ограничены, чтобы предотвратить превышение суммарного количества неполных вызовов в памяти (в байтах) размера стека (в байтах).
вот пример рекурсивного алгоритма для реверсирования односвязного списка. На ноутбуке со следующей спецификацией (память 4G, процессор Intel Core i5 2.3 GHz, 64 бит Windows 7) эта функция будет работать с ошибкой StackOverflow для связанного списка размера, близкого к 10,000.
Я считаю, что мы должны использовать рекурсию разумно, всегда принимая во внимание масштаб системы. Часто рекурсию можно преобразовать в итеративную программу, которая лучше масштабируется. (Одна итерация версия того же алгоритма приведена в нижней части страницы, она отменяет односвязный список размером 1 миллион за 9 миллисекунд.)
итеративная версия того же алгоритма:
A StackOverflowError является ошибкой времени выполнения в java.
он выбрасывается при превышении объема памяти стека вызовов, выделенного JVM.
обычный случай a StackOverflowError выбрасывается, когда стек вызовов превышает из-за чрезмерной глубокой или бесконечной рекурсии.
в вышеуказанном случае можно избежать выполнения программных изменений. Но если логика программы правильная и все же она происходит то, что вам нужно увеличить размер стека.
StackOverflowError в основном, когда вы пытаетесь что-то сделать, что, скорее всего, называет себя и продолжается бесконечно (или пока он не дает StackOverflowError).
add5(a) вызовет себя, а затем вызовет себя снова и так далее.
термин» переполнение стека (переполнение) » часто используется, но неправильно; атаки не переполняют стек, а буферы в стеке.
What is a StackOverflowError?
15 Answers 15
Parameters and local variables are allocated on the stack (with reference types, the object lives on the heap and a variable in the stack references that object on the heap). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (i.e. towards zero).
Your process also has a heap, which lives at the bottom end of your process. As you allocate memory, this heap can grow towards the upper end of your address space. As you can see, there is a potential for the heap to «collide» with the stack (a bit like tectonic plates. ).
The common cause for a stack overflow is a bad recursive call. Typically, this is caused when your recursive functions doesn’t have the correct termination condition, so it ends up calling itself forever. Or when the termination condition is fine, it can be caused by requiring too many recursive calls before fulfilling it.
However, with GUI programming, it’s possible to generate indirect recursion. For example, your app may be handling paint messages, and, whilst processing them, it may call a function that causes the system to send another paint message. Here you’ve not explicitly called yourself, but the OS/VM has done it for you.
To deal with them, you’ll need to examine your code. If you’ve got functions that call themselves then check that you’ve got a terminating condition. If you have, then check that when calling the function you have at least modified one of the arguments, otherwise there’ll be no visible change for the recursively called function and the terminating condition is useless. Also mind that your stack space can run out of memory before reaching a valid terminating condition, thus make sure your method can handle input values requiring more recursive calls.
If you’ve got no obvious recursive functions then check to see if you’re calling any library functions that indirectly will cause your function to be called (like the implicit case above).
Что вызывает java.lang.StackOverflowError
Проверьте наличие повторных вызовов методов. В основном это вызвано рекурсивным вызовом метода. Простой пример:
Здесь System.out.println (i); будет многократно помещаться в стек при вызове testMethod.
Обычно причиной этого является бесконечная рекурсия, но если бы вы это видели, ваша трассировка стека имела бы более 5 кадров.
На самом деле причиной java.lang.StackOverflowError обычно является непреднамеренная рекурсия. Для меня это часто, когда я намеревался вызвать супер-метод для скрытого метода. Например, в этом случае:
Во-первых, полезно знать, что происходит за кулисами, когда мы вызываем функцию. Аргументы и адрес того места, где был вызван метод, помещаются в стек (см. 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 обычно довольно легко разрешить, если он возникает.
Теоретически также возможно переполнение стека без рекурсии, но на практике это может показаться довольно редким событием.
Что такое java.lang.StackOverflowError
Ошибка java.lang.StackOverflowError выдается, чтобы указать, что стек приложения был исчерпан из-за глубокой рекурсии, то есть ваша программа / сценарий рекурсии слишком глубоко.
Детали
Пример
Minimal, Complete, and Verifiable Example :
Консольный выход
Объяснение
Наиболее частым случаем, который может исчерпать стек Java-приложения, является рекурсия. В рекурсии метод вызывает себя во время выполнения. Recursion один из самых мощных методов программирования общего назначения, но его следует использовать с осторожностью, StackOverflowError чтобы избежать ошибок.