2010-01-24 17 views
55

Estoy ejecutando un programa que he escrito en Java en Eclipse. El programa tiene un nivel de recursión muy profundo para entradas muy grandes. Para las entradas más pequeños el programa funciona muy bien sin embargo cuando se dan grandes entradas, me sale el siguiente error:Error de desbordamiento de la pila de Java: ¿cómo aumentar el tamaño de la pila en Eclipse?

Exception in thread "main" java.lang.StackOverflowError 

Puede esto ser resueltos mediante el aumento del tamaño de la pila de Java y si es así, ¿cómo puedo hacer esto en Eclipse?

Actualización:

@ Jon Skeet

El código está atravesando un árbol de análisis de forma recursiva con el fin de construir una estructura de datos. Entonces, por ejemplo, el código hará algún trabajo usando un nodo en el árbol de análisis sintáctico y se llamará a sí mismo en los dos hijos del nodo, combinando sus resultados para dar el resultado global para el árbol.

La profundidad total de la recursión depende del tamaño del árbol de análisis pero el código parece fallar (sin una pila más grande) cuando el número de llamadas recursivas entra en los 1000.

También estoy bastante seguro de que el código no está fallando debido a un error, ya que funciona para pequeñas entradas.

+7

algo está mal aquí ... stackoverflow (.com) no es un error! :-) –

Respuesta

72

Abra Ejecute la configuración para su aplicación (Ejecutar/Ejecutar configuraciones ..., luego busque la entrada de aplicaciones en 'aplicación Java').

El argumentos pestaña tiene un cuadro de texto argumentos de VM, introduzca -Xss1m (o un parámetro más grande para el tamaño máximo de pila). El valor predeterminado es 512 kByte (SUN JDK 1.5 - no sé si varía entre proveedores y versiones).

+2

Tenga en cuenta este problema: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6316197 –

10

Agregue la marca -Xss1024k en los Argumentos VM.

También puede aumentar el tamaño de la pila en mb utilizando -Xss1m por ejemplo.

37

Se puede ser curable mediante el aumento del tamaño de la pila -, pero una solución mejor habría que encontrar la manera de evitar de manera recursiva tanto. Una solución recursiva siempre se puede convertir a una solución iterativa, lo que hará que su código se adapte a entradas más grandes de forma mucho más limpia. De lo contrario, estarás adivinando cuánta pila se debe proporcionar, lo que puede no ser obvio a partir de la entrada.

¿Está seguro de que está fallando debido al tamaño de la entrada en lugar de un error en el código, por cierto? ¿Cuán profunda es esta recursión?

EDITAR: De acuerdo, habiendo visto la actualización, yo personalmente trataría de reescribirla para evitar el uso de la recursión. En general, tener un Stack<T> de "las cosas aún le sirven" es un buen punto de partida para eliminar la recursividad.

+4

..or recidiva final. – BalusC

+0

No puedo recordar el estado de recursión de cola en jvms. Cue comentario de tackline –

+1

Las JVM todavía no suelen optimizar las repeticiones de cola. Creo que esta es una de las cosas que la generalización de la JVM a lenguajes que no son Java es arreglar. –

3

Necesita tener una configuración de inicio dentro de Eclipse para ajustar los parámetros de JVM.

Después de ejecutar su programa con F11 o Ctrl-F11, abra las configuraciones de ejecución en Ejecutar -> Configuraciones de ejecución ... y abra su programa en "Aplicaciones Java". Seleccione el panel Argumentos, donde encontrará "argumentos VM".

Aquí es donde va -Xss1024k.

Si desea que la configuración de inicio sea un archivo en su espacio de trabajo (para que pueda hacer clic derecho y ejecutarlo), seleccione el panel Común y marque la casilla Guardar como -> Archivo compartido y busque la ubicación que desee el archivo de lanzamiento. Normalmente los tengo en una carpeta separada, ya que los revisamos en CVS.

5

también tengo el mismo problema al analizar los archivos de definición de esquema (XSD) usando la biblioteca XSOM,

yo era capaz de aumentar la memoria de pila hasta 208Mb entonces se mostró heap_out_of_memory_error para el que yo era capaz de aumentar solamente hasta 320mb.

la configuración final era -Xmx320m -Xss208m pero luego se ejecutó durante un tiempo y falló.

Mi función imprime recursivamente todo el árbol de la definición del esquema, sorprendentemente el archivo de salida cruzó 820Mb para un archivo de definición de 4 Mb (biblioteca Aixm) que a su vez usa 50 Mb de biblioteca de definición de esquema (ISO gml).

con eso estoy convencido de que tengo que evitar la recursión y luego comenzar la iteración y alguna otra forma de representación de la salida, pero no tengo problemas para convertir toda esa recursión en iteración.

2

Cuando el argumento -Xss no hace el trabajo de tratar de eliminar los archivos temporales de:

c:\Users\{user}\AppData\Local\Temp\. 

Esto hizo el truco para mí.

0

Observe el cruce de árboles en orden de Morris que utiliza espacio constante y se ejecuta en O (n) (hasta 3 veces más que su recorrido recursivo normal, pero ahorra mucho en espacio). Si los nodos son modificables, entonces puede guardar el resultado calculado del subárbol mientras retrocede a su raíz (escribiendo directamente al Nodo).

Cuestiones relacionadas