一、前言
最近在项目开发中遇到一个bug,方法中使用递归进行数据处理导致栈溢出抛出StackOverflowError错误,下面来模拟一下场景。
二、场景模拟
package jdk;
/**
* @Description 栈溢出 StackOverflowError
* @Author King
* @Date 2020/4/29 16:25
* @Version 1.0
**/
public class StackOverflowMain {
/**
* 栈溢出 大小
*/
private static int num;
public static void main(String[] args) {
recursive();
}
/**
* 递归实现不断压栈
*/
private static void recursive() {
System.out.println(num++);
recursive();
}
}
三、原因分析
我们都知道方法运行就是不断压栈出栈的过程,在递归方法中,如果没有限制递归次数,则会导致在新建栈帧的时候,栈空间不足导致栈溢出。
四、解决方案(开源节流)
1、开源
既然栈空间不足,那我们可以加大jvm中栈内存大小,java -X命令可以查看jvm非标准参数。在项目启动参数中修改-Xss大小即可。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。
结果:是不是比之前大了呢
2、节流
既然堆栈大小固定,那么可以限定压栈次数。所以我们在写代码慎重使用递归或者约定递归次数。
/**
* 递归实现不断压栈
*/
private static void recursive() {
System.out.println(num++);
// 限制递归次数
while (num < 1000) {
recursive();
}
}