How to avoid StackOverflowError for a recursive function

China☆狼群 提交于 2019-11-29 16:59:30

问题


I'm writing a function that will call itself up to about 5000 times. Ofcourse, I get a StackOverflowError. Is there any way that I can rewrite this code in a fairly simple way?:

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

}

By the way, what is the limitation of how deep we may call the functions?


回答1:


Use an explicit stack of objects and a loop, rather than the call stack and recursion:

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);
  }
}



回答2:


default stack size in java is 512kb. if you exceed that program will terminate throwing StackOverflowException

you can increase the stack size by passing a JVM argument : -Xss1024k

now stack size is 1024kb. you may give higher value based on your environment

I don't think we can programmatically change this




回答3:


You can increase the stack size by using -Xss4m.




回答4:


You may put your "Block"s into a queue/stack and iterate as long as Blocks are available.




回答5:


It's obvious that you get StackOverflow with such branching factor of your recursion. In other languages it can be achieved by Tail Call Optimization. But I suppose your problem needs another way to solve.

Ideally, you perform some check on Block. Maybe you can obtain list of all blocks and check each of them iteratively?




回答6:


In most cases recursion is used in a wrong way. You shouldn't get a stack over flow exception. Your method has no return type/value. How do you ensure your initial Block b is valid?

If you are using recursion, answer yourself the following question:

  • what is my recursion anchor (when do i stop with recursion)
  • what is my recursion step (how do I reduce my number of calculations)

Example:

  • n! => n*n-1!

my recursion anchor is n == 2 (result is 2), so I can calculate all results beginnging from this anchor.

my recursion step is n-1 (so each step I get closer to the solution (and in this fact to my recursion anchor))



来源:https://stackoverflow.com/questions/10073471/how-to-avoid-stackoverflowerror-for-a-recursive-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!