Что может вызвать java.lang.StackOverflowError
? Распечатка стека, которую я получаю, совсем не очень глубокая (всего 5 методов).
87
Что может вызвать java.lang.StackOverflowError
? Распечатка стека, которую я получаю, совсем не очень глубокая (всего 5 методов).
Ответы:
Проверьте наличие повторных вызовов методов. В основном это вызвано рекурсивным вызовом метода. Простой пример:
public static void main(String... args) { Main main = new Main(); main.testMethod(1); } public void testMethod(int i) { testMethod(i); System.out.println(i); }
Здесь System.out.println (i); будет многократно помещаться в стек при вызове testMethod.
источник
Одним из (необязательных) аргументов JVM является размер стека. Это -Xss. Я не знаю, что такое значение по умолчанию, но если общее количество материала в стеке превышает это значение, вы получите эту ошибку.
Обычно причиной этого является бесконечная рекурсия, но если бы вы это видели, ваша трассировка стека имела бы более 5 кадров.
Попробуйте добавить аргумент -Xss (или увеличить его значение), чтобы увидеть, исчезнет ли это.
источник
На самом деле причиной java.lang.StackOverflowError обычно является непреднамеренная рекурсия. Для меня это часто, когда я намеревался вызвать супер-метод для скрытого метода. Например, в этом случае:
public class Vehicle { public void accelerate(float acceleration, float maxVelocity) { // set the acceleration } } public class SpaceShip extends Vehicle { @Override public void accelerate(float acceleration, float maxVelocity) { // update the flux capacitor and call super.accelerate // oops meant to call super.accelerate(acceleration, maxVelocity); // but accidentally wrote this instead. A StackOverflow is in our future. this.accelerate(acceleration, maxVelocity); } }
Во-первых, полезно знать, что происходит за кулисами, когда мы вызываем функцию. Аргументы и адрес того места, где был вызван метод, помещаются в стек (см. 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
выдается, чтобы указать, что стек приложения был исчерпан из-за глубокой рекурсии, то есть ваша программа / сценарий рекурсии слишком глубоко.Детали
Класс
StackOverflowError
extends,VirtualMachineError
который указывает, что JVM исчерпали или исчерпали ресурсы и не может работать дальше.VirtualMachineError
, Который расширяетError
класс используется для указания тех серьезных проблем , что приложение не должно поймать. Метод может не объявлять такие ошибки в своемthrow
разделе, потому что эти ошибки являются ненормальными условиями, которые никогда не ожидались.Пример
Minimal, Complete, and Verifiable Example
:package demo; public class StackOverflowErrorExample { public static void main(String[] args) { StackOverflowErrorExample.recursivePrint(1); } public static void recursivePrint(int num) { System.out.println("Number: " + num); if(num == 0) return; else recursivePrint(++num); } }
Консольный выход
Number: 1 Number: 2 . . . Number: 8645 Number: 8646 Number: 8647Exception in thread "main" java.lang.StackOverflowError at java.io.FileOutputStream.write(Unknown Source) at java.io.BufferedOutputStream.flushBuffer(Unknown Source) at java.io.BufferedOutputStream.flush(Unknown Source) at java.io.PrintStream.write(Unknown Source) at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source) at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source) at sun.nio.cs.StreamEncoder.flushBuffer(Unknown Source) at java.io.OutputStreamWriter.flushBuffer(Unknown Source) at java.io.PrintStream.newLine(Unknown Source) at java.io.PrintStream.println(Unknown Source) at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:11) at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16) . . . at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
Объяснение
Когда вызов функции вызывается приложением Java, в стеке вызовов выделяется кадр стека .
stack frame
Содержит параметры, вызываемый метод его локальных параметров, а также обратный адрес метода. Адрес возврата обозначает точку выполнения, с которой выполнение программы должно продолжаться после возврата из вызванного метода. Если нет места для нового кадра стека, тоStackOverflowError
виртуальная машина Java (JVM) выбрасывает его.Наиболее частым случаем, который может исчерпать стек Java-приложения, является рекурсия. В рекурсии метод вызывает себя во время выполнения.
Recursion
один из самых мощных методов программирования общего назначения, но его следует использовать с осторожностью,StackOverflowError
чтобы избежать ошибок.Ссылки
источник
Когда вызов функции вызывается приложением Java, в стеке вызовов выделяется кадр стека. Кадр стека содержит параметры вызываемого метода, его локальные параметры и адрес возврата метода.
Адрес возврата обозначает точку выполнения, с которой выполнение программы должно продолжаться после возврата из вызванного метода. Если нет никакого пространства для нового кадра стека пор StackOverflowError выбрасывается в виртуальной машине Java (JVM) .
Наиболее частым случаем, который может исчерпать стек Java-приложения, является рекурсия.
Пожалуйста, посмотрите
Как решить StackOverflowError
источник
Решение для пользователей Hibernate при парсинге данных:
У меня была эта ошибка, потому что я анализировал список объектов, сопоставленных с обеих сторон,
@OneToMany
и@ManyToOne
json с помощью jackson, что вызвало бесконечный цикл.Если вы находитесь в такой же ситуации , вы можете решить эту проблему с помощью
@JsonManagedReference
и@JsonBackReference
аннотаций.Определения из API:
JsonManagedReference ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonManagedReference.html ):
JsonBackReference: ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonBackReference.html ):
Пример:
Owner.java:
@JsonManagedReference @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER) Set<Car> cars;
Car.java:
@JsonBackReference @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "owner_id") private Owner owner;
Другое решение - использовать,
@JsonIgnore
который просто установит значение null в поле.источник
Я создал программу с hibernate, в которой я создал два класса POJO, оба с объектами друг друга в качестве членов данных. Когда в основном методе я пытался сохранить их в базе данных, я также получил эту ошибку.
Это происходит потому, что оба класса ссылаются друг на друга, следовательно, создается цикл, вызывающий эту ошибку.
Итак, проверьте, существуют ли такие отношения в вашей программе.
источник
Исключения переполнения стека могут возникать, когда стек потока продолжает увеличиваться в размере до достижения максимального предела.
Настройка параметров размера стека (Xss и Xmso) ...
Я предлагаю вам увидеть эту ссылку: http://www-01.ibm.com/support/docview.wss?uid=swg21162896 Существует много возможных причин StackOverflowError, как вы можете видеть по ссылке ....
источник
В моем случае у меня есть два занятия. Во втором упражнении я забыл поставить super на метод onCreate.
super.onCreate(savedInstanceState);
источник
StackOverflowError
, я не думаю, что он отвечает на вопрос. Я думаю, что правильный ответ должен либо перечислить другие способы получить это исключение, кроме использования слишком большой рекурсии, либо сказать, что определенно нет другого способа получить такое исключение, кроме как выбросить его вручную.