2012-04-09 36 views
14

Estoy escribiendo una función que se autodenominará hasta unas 5000 veces. Por supuesto, obtengo una StackOverflowException. ¿Hay alguna manera de que pueda volver a escribir el código de una manera bastante sencilla ?:Java: Cómo evitar StackOverflowException

void checkBlocks(Block b, int amm) { 

    //Stuff that might issue a return call 

    Block blockDown = (Block) b.getRelative(BlockFace.DOWN); 
    if (condition) 
     checkBlocks(blockDown, amm); 


    Block blockUp = (Block) b.getRelative(BlockFace.UP); 
    if (condition) 
     checkBlocks(blockUp, amm); 

    //Same code 4 more times for each side 

} 

Por cierto, ¿cuál es la limitación de la profundidad que podríamos llamar las funciones?

Gracias!

+0

http://stackoverflow.com/questions/214741/what-is -a-stack-overflow-error –

Respuesta

17

¿Quizás usando una pila?

void checkBlocks(Block b, int amm) { 
    Stack<Block> blocks = new Stack<Block>(); 
    blocks.push(b); 
    while (!blocks.isEmpty()) { 
    b = blocks.pop(); 
    Block blockDown = (Block) b.getRelative(BlockFace.DOWN); 
    if (condition) 
     blocks.push(block); 
    Block blockUp = (Block) b.getRelative(BlockFace.UP); 
    if (condition) 
     blocks.push(block); 
    } 
} 
+0

Muchas gracias, funciona muy bien. Esa clase probablemente sea útil muchas más veces más adelante. Ty! –

0

Puede aumentar el tamaño de la pila con -Xss4m.

+0

Pero, ¿y si el tamaño de la placa sigue aumentando?Creo que se dio cuenta de esto y no preguntó cómo aumentar el tamaño de la pila, sino cómo refactorizar el código. – barsju

0

Puede colocar sus "Bloques" en una cola/pila e iterar siempre que haya Bloques disponibles.

0

Es obvio que obtiene StackOverflow con tal factor de ramificación de su recursión. En otros idiomas se puede lograr by Tail Call Optimization. Pero supongo que su problema necesita otra forma de resolverlo.

Lo ideal es que controle Block. ¿Tal vez puedas obtener una lista de todos los bloques y verificarlos de forma iterativa?

4

El tamaño de pila predeterminado en java es 512kb. si se excede ese programa terminará lanzando StackOverflowException

puede aumentar el tamaño de la pila al pasar un argumento de JVM: -Xss1024k

ahora tamaño de la pila es 1024 KB. puede dar mayor valor en función de su entorno

No creo que nos podemos cambiar mediante programación esta

0

En la mayoría de los casos la recursividad se utiliza de una manera incorrecta. No deberías obtener una excepción de stack over flow. Su método no tiene devolución tipo/valor. ¿Cómo se asegura que su Bloque inicial b sea válido?

Si está utilizando la recursividad, responder sí mismo la siguiente pregunta: ¿

  • lo que es mi recursividad de anclaje (cuando hago para dejar con la recursividad)
  • lo que es mi paso recursividad (¿cómo puedo reducir mi número de cálculos)

Ejemplo:

  • n! => n * n-1!

my recursión de anclaje es n == 2 (resultado es 2), por lo que puedo calcular todos los resultados a partir de este ancla.

mi paso recursividad es n-1 (por lo que cada paso que estar más cerca de la solución (y en este hecho para mi ancla recursividad))

Cuestiones relacionadas