significado - Error de desbordamiento de la pila Java: ¿cómo aumentar el tamaño de la pila en Eclipse?
stack overflow significado (7)
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 entradas más pequeñas, el programa funciona bien; sin embargo, cuando se dan entradas grandes, obtengo el siguiente error:
Exception in thread "main" java.lang.StackOverflowError
¿Esto se puede resolver aumentando el tamaño de la pila de Java y, de ser así, cómo lo hago en Eclipse?
Actualizar:
@Jon Skeet
El código está atravesando un árbol de análisis recursivo para 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 sintáctico, pero el código parece fallar (sin una pila más grande) cuando la cantidad de llamadas recursivas llega a 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.
Abra la Configuración de Ejecución para su aplicación (Ejecutar / Ejecutar Configuraciones ..., luego busque la entrada de aplicaciones en ''Aplicación Java'').
La pestaña de argumentos tiene un cuadro de texto Vm arguments , ingrese -Xss1m
(o un parámetro más grande para el tamaño máximo de la pila). El valor predeterminado es 512 kByte (SUN JDK 1.5 - no sé si varía entre proveedores y versiones).
Agregue el indicador -Xss1024k
en los Argumentos VM.
También puede aumentar el tamaño de la pila en mb
utilizando -Xss1m
por ejemplo.
Cuando el argumento -Xss
no -Xss
, intente eliminar los archivos temporales de:
c:/Users/{user}/AppData/Local/Temp/.
Esto hizo el truco para mí.
Debe 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 inicio 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 con el botón derecho y ejecutarlo), seleccione el panel Común y marque la casilla Guardar como -> Archivo compartido y busque la ubicación que desea que ejecute el archivo. Normalmente los tengo en una carpeta separada, ya que los revisamos en CVS.
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).
También tengo el mismo problema al analizar archivos de definición de esquema (XSD) usando la biblioteca XSOM.
Pude aumentar la memoria de apilamiento hasta 208Mb luego mostró heap_out_of_memory_error
para el cual pude aumentar solo hasta 320mb.
la configuración final era -Xmx320m -Xss208m
pero luego se ejecutó por un tiempo y falló.
Mi función imprime recursivamente todo el árbol de la definición de esquema, increíblemente 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 Recursion y luego comenzar la iteración y alguna otra forma de representar el resultado, pero estoy teniendo pocos problemas para convertir toda esa recursión en iteración.
Puede ser curable al aumentar el tamaño de la pila, pero una mejor solución sería averiguar cómo evitar recurrir 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ás 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, personalmente intentaré reescribirla para evitar el uso de la recursión. En general, tener una Stack<T>
de "las cosas aún le sirven" es un buen punto de partida para eliminar la recursividad.