¿Qué puede causar un java.lang.StackOverflowError
? La copia impresa de la pila que obtengo no es muy profunda (solo 5 métodos).
87
¿Qué puede causar un java.lang.StackOverflowError
? La copia impresa de la pila que obtengo no es muy profunda (solo 5 métodos).
Respuestas:
Compruebe si hay llamadas recusivas a los métodos. Principalmente se produce cuando hay una llamada recursiva a un método. Un ejemplo simple es
public static void main(String... args) { Main main = new Main(); main.testMethod(1); } public void testMethod(int i) { testMethod(i); System.out.println(i); }
Aquí el System.out.println (i); se enviará repetidamente a la pila cuando se llame a testMethod.
fuente
Uno de los argumentos (opcionales) de la JVM es el tamaño de la pila. Es -Xss. No sé cuál es el valor predeterminado, pero si la cantidad total de cosas en la pila excede ese valor, obtendrá ese error.
Generalmente, la recursividad infinita es la causa de esto, pero si estuviera viendo eso, su seguimiento de pila tendría más de 5 marcos.
Intente agregar un argumento -Xss (o aumentar el valor de uno) para ver si esto desaparece.
fuente
Lo que en realidad causa un java.lang.StackOverflowError es típicamente una recursividad involuntaria. Para mí, es a menudo cuando tenía la intención de llamar a un súper método para el método invalidado. Como en este caso:
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); } }
Primero, es útil saber qué sucede detrás de escena cuando llamamos a una función. Los argumentos y la dirección de donde se llamó al método se insertan en la pila (consulte http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management ) para que el método llamado pueda acceder a los argumentos y para que cuando el método llamado se completa, la ejecución puede continuar después de la llamada. Pero como llamamos a this.accelerate (aceleración, maxVelocity) de forma recursiva (la recursión es poco estricta cuando un método se llama a sí mismo. Para obtener más información, consulte http://en.wikipedia.org/wiki/Recursion_(computer_science)) nos encontramos en una situación conocida como recursividad infinita y seguimos acumulando los argumentos y la dirección de retorno en la pila de llamadas. Dado que la pila de llamadas tiene un tamaño finito, eventualmente nos quedamos sin espacio. La falta de espacio en la pila de llamadas se conoce como desbordamiento. Esto se debe a que estamos tratando de usar más espacio de pila del que tenemos y los datos literalmente desbordan la pila. En el lenguaje de programación Java, esto da como resultado la excepción de tiempo de ejecución java.lang.StackOverflow e inmediatamente detendrá el programa.
El ejemplo anterior está algo simplificado (aunque me pasa más de lo que me gustaría admitir). Lo mismo puede suceder de una manera más redonda, lo que hace que sea un poco más difícil de localizar. Sin embargo, en general, StackOverflow suele ser bastante fácil de resolver, una vez que ocurre.
En teoría, también es posible tener un desbordamiento de pila sin recursividad, pero en la práctica, parecería ser un evento bastante raro.
fuente
Que es
java.lang.StackOverflowError
El error se
java.lang.StackOverflowError
produce para indicar que la pila de la aplicación se agotó, debido a una recursividad profunda, es decir, su programa / secuencia de comandos se repite demasiado.Detalles
La clase
StackOverflowError
amplíaVirtualMachineError
que indica que la JVM se ha quedado o se ha quedado sin recursos y no puede seguir funcionando. ElVirtualMachineError
que extiende laError
clase se usa para indicar aquellos problemas serios que una aplicación no debería detectar. Un método puede no declarar tales errores en suthrow
cláusula porque estos errores son condiciones anormales que nunca se esperaba que ocurrieran.Un ejemplo
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); } }
Salida de consola
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)
Explicacion
Cuando una aplicación Java invoca una llamada a una función, se asigna un marco de pila en la pila de llamadas . El
stack frame
contiene los parámetros del método invocado, sus parámetros locales, y la dirección de retorno del método. La dirección de retorno denota el punto de ejecución desde el cual, la ejecución del programa continuará después de que regrese el método invocado. Si no hay espacio para un nuevo marco de pila,StackOverflowError
el Java Virtual Machine (JVM) lo lanza.El caso más común que posiblemente puede agotar la pila de una aplicación Java es la recursividad. En recursividad, un método se invoca a sí mismo durante su ejecución.
Recursion
una de las técnicas de programación de propósito general más poderosas, pero debe usarse con precaución paraStackOverflowError
evitarlo.Referencias
fuente
Cuando una aplicación Java invoca una llamada a una función, se asigna un marco de pila en la pila de llamadas. El marco de pila contiene los parámetros del método invocado, sus parámetros locales y la dirección de retorno del método.
La dirección de retorno indica el punto de ejecución desde el cual, la ejecución del programa continuará después de que regrese el método invocado. Si no hay espacio para un nuevo marco de pila, la máquina virtual Java (JVM) lanza StackOverflowError .
El caso más común que posiblemente puede agotar la pila de una aplicación Java es la recursividad.
Por favor échale un vistazo
Cómo resolver StackOverflowError
fuente
Solución para usuarios de Hibernate al analizar datos:
Tuve este error porque estaba analizando una lista de objetos mapeados en ambos lados
@OneToMany
y@ManyToOne
json usando jackson, lo que provocó un bucle infinito.Si se encuentra en la misma situación, puede solucionarlo utilizando las anotaciones
@JsonManagedReference
y@JsonBackReference
.Definiciones de 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 ):
Ejemplo:
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;
Otra solución es usar
@JsonIgnore
que simplemente establecerá nulo en el campo.fuente
Creé un programa con hibernación, en el que creé dos clases POJO, ambas con un objeto el uno del otro como miembros de datos. Cuando en el método principal intenté guardarlos en la base de datos, también obtuve este error.
Esto sucede porque ambas clases se refieren entre sí, por lo que se crea un bucle que causa este error.
Por lo tanto, verifique si existe ese tipo de relaciones en su programa.
fuente
Las excepciones de desbordamiento de pila pueden ocurrir cuando una pila de subprocesos continúa creciendo en tamaño hasta alcanzar el límite máximo.
Ajuste de las opciones de Tamaños de pila (Xss y Xmso) ...
Le sugiero que vea este enlace: http://www-01.ibm.com/support/docview.wss?uid=swg21162896 Hay muchas causas posibles para un StackOverflowError, como puede ver en el enlace ...
fuente
En mi caso tengo dos actividades. En la segunda actividad, olvidé poner super en el método onCreate.
super.onCreate(savedInstanceState);
fuente
StackOverflowError
, no creo que esté respondiendo a la pregunta. Creo que una respuesta adecuada debería enumerar otras formas de obtener esta excepción además de usar demasiada recursividad o decir que definitivamente no hay otra forma de obtener dicha excepción, excepto lanzarla manualmente.