You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归会导致Java或Java IDE崩溃吗?递归求素数遇StackOverflowError

递归导致的StackOverflowError问题解析

嘿,你遇到的这个java.lang.StackOverflowError本质原因很明确:递归调用的层数太深,耗尽了Java线程的栈内存。

具体成因

Java里每个线程都有一块固定大小的调用栈(默认大小通常在几百KB到几MB之间,由JVM配置决定)。每次调用recursion()方法时,JVM都会在栈中创建一个新的「栈帧」,用来存储方法的参数、局部变量和返回地址。

你的代码逻辑是:每检查一个数字(不管是不是素数),都会递归调用一次recursion()。从12开始到4330左右,已经产生了四千多次连续的递归调用——每一次调用都占着栈空间,当栈帧的总数超过JVM允许的上限时,自然就抛出栈溢出错误了。

你说能运行到4330但没法更大,就是因为到这个数值时,栈空间刚好被耗尽。这和IDE(Eclipse Neon)没啥关系,是Java虚拟机的栈内存限制导致的。

解决方案:用迭代替代递归

递归虽然写法简洁,但这种需要连续调用几千次的场景,完全不适合用递归——换成循环(迭代)就能彻底解决问题,因为迭代不会不断创建新的栈帧,而是在同一个栈帧里重复执行逻辑。

修改后的代码示例:

import java.util.ArrayList;

public class LargePrimeNumber {

    static ArrayList<Integer> PrimeDataBase = new ArrayList<>();
    static int cd = 12;

    public static void main(String[] args) {
        PrimeDataBase.add(2);
        PrimeDataBase.add(3);
        PrimeDataBase.add(5);
        PrimeDataBase.add(7);
        PrimeDataBase.add(11);
        
        // 用while循环替代递归逻辑
        while (cd < 5000) {
            boolean prime = true;
            // 优化:只检查到cd的平方根,减少循环次数
            int sqrtCd = (int) Math.sqrt(cd);
            for (int i = 0; i < PrimeDataBase.size(); i++) {
                int primeNum = PrimeDataBase.get(i);
                if (primeNum > sqrtCd) {
                    break;
                }
                if (cd % primeNum == 0) {
                    prime = false;
                    break;
                }
            }
            if (prime) {
                PrimeDataBase.add(cd);
                System.out.println(cd + " is prime");
            }
            cd++;
        }
    }
}

额外提个小优化:检查素数时,不需要遍历所有已有的素数,只需要检查到cd的平方根就够了——因为如果一个数有大于其平方根的因数,必然对应一个小于平方根的因数,这样能大幅减少循环次数,提升程序效率。

内容的提问来源于stack exchange,提问作者Kenneth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:13:44