Java 如何避免递归函数的堆栈溢出错误

Java 如何避免递归函数的堆栈溢出错误,java,stack-overflow,Java,Stack Overflow,我正在编写一个函数,它将调用自己大约5000次。当然,我得到了一个堆栈溢出错误。有什么方法可以让我用一种相当简单的方式重写这段代码吗 void checkBlocks(Block b, int amm) { //Stuff that might issue a return call Block blockDown = (Block) b.getRelative(BlockFace.DOWN); if (condition) checkBlocks(

我正在编写一个函数,它将调用自己大约5000次。当然,我得到了一个
堆栈溢出错误
。有什么方法可以让我用一种相当简单的方式重写这段代码吗

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

}

顺便问一下,调用函数的深度有什么限制?

使用对象的显式堆栈和循环,而不是调用堆栈和递归:

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);
  }
}
无效检查块(块b,int amm){
堆栈块=新堆栈();
块。推(b);
而(!blocks.isEmpty()){
b=blocks.pop();
Block blockDown=(Block)b.getRelative(BlockFace.DOWN);
如果(条件)
推(块);
Block blockUp=(Block)b.getRelative(BlockFace.UP);
如果(条件)
推(块);
}
}

您可以使用-Xss4m增加堆栈大小

您可以将“块”放入队列/堆栈,并在块可用的情况下进行迭代。

很明显,递归的这种分支因子会导致堆栈溢出。在其他语言中,这是可以实现的。但我想你的问题需要另一种方法来解决


理想情况下,对块执行一些检查。也许您可以获得所有块的列表,并反复检查每个块?

java中的默认堆栈大小为512kb。如果超过该值,程序将终止抛出StackOverflowException

您可以通过传递JVM参数来增加堆栈大小: -Xss1024k

现在堆栈大小为1024kb。您可以根据您的环境提供更高的价值


我不认为我们可以通过编程来改变这一点,在大多数情况下,递归是以错误的方式使用的。您不应该得到堆栈溢出异常。 您的方法没有返回类型/值。 您如何确保您的初始区块b有效

如果使用递归,请回答以下问题:

  • 我的递归锚是什么(我什么时候停止递归)
  • 递归步骤是什么(如何减少计算次数)
例如:

  • n!=>n*n-1
我的递归锚点是n==2(结果是2),所以我可以计算从这个锚点开始的所有结果


我的递归步骤是n-1(因此每一步我都离解决方案越来越近(事实上,我离递归锚点越来越近))

但是如果电路板大小一直在增加呢?我想他意识到了这一点,并没有问如何增加堆栈大小,而是问如何重构代码!