StackOverFlow 的奇怪 Java 乘法递归

Strange Java Multiplication Recursion with StackOverFlow

Java 程序使用迭代和递归正确运行。但出于某种奇怪的原因,我无法理解的是,当我输入的数字超过 9200 时,我会得到一个 Whosebug。我尝试更改为 long 但这就是我能想到的。关于这种情况如何以及为何发生以及我该如何解决以便它可以计算任何数字的任何想法?

import java.util.Scanner;

public class Multiplication {

    public static long multiIterative(long a, long b) {
        long result = 0;
        while (b > 0) {
            result += a;
            b--;
        }
        return result;
    }

    public static long multiRecursive(long a, long b) {
        if (a == 0 || b == 0) {
            return 0;
        }
        return a + multiRecursive(a, b - 1);
    }

    public static void main(String[] args) {
        Scanner userInput = new Scanner(System.in);
        System.out.print("Please enter first Integer: ");
        long a = userInput.nextInt();
        System.out.print("Please enter second Integer: ");
        long b = userInput.nextInt();
        System.out.println("The Multiplication Iteration would be: " + multiIterative(a, b));
        System.out.println("The Multiplication Recursion would be: " + multiRecursive(a, b));
    }

}

递归使用栈来存储到达终止条件之前的函数调用,这会导致栈中的项目弹出并生成最终结果。

java函数栈的大小取决于分配给栈的虚拟内存。您可以尝试通过为 -Xss JVM 参数设置适当的值来微调它。

如果递归根据输入值越来越深,那么您应该考虑分解任务。

取自http://en.wikipedia.org/wiki/Stack_overflow

The other major cause of a stack overflow results from an attempt to allocate more memory on the stack than will fit, for example by creating local array variables that are too large.

Juned Ahsan 是对的,您可以尝试增加堆大小以适应您的递归。看看这个 link:

Java stack overflow error - how to increase the stack size in Eclipse?

在Java中,每次方法调用都会在栈上放一条激活记录,直到调用完成。递归产生与方法调用一样多的激活记录。因此,与本质上使用 goto 语句的迭代设计相比,递归算法不能 运行 无限深入;因此这是递归算法设计的局限之一。

考虑这两个文件:IterationTest.java将运行永远快乐(使用ctrl + c终止文件的执行如果运行在 Bash 终端上运行,例如在 Linux 中),而 RecursionTest.java 几乎会立即失败。

/*
 * Runs perfectly fine forever 
 * (use ctrl + c to escape execution in terminal, if on Linux)
 */
public class IterationTest
{
    public static void printMe()
    {
        while(true)
        {
            System.out.println("iteration");
        }
    }
    public static void main(String[] args)
    {
        printMe();
    }
}

/*
 * Guaranteed Whosebug error using infinite recursion
 */
 public class RecursionTest
{
    public static void printMe()
    {
        System.out.println("iteration");
        printMe();
    }

    public static void main(String[] args)
    {
        printMe();
    }
}