java.lang.StackOverflowError出现的原因及解决

 更新时间:2022年07月01日 08:51:34   作者:psh1234  
这篇文章主要介绍了java.lang.StackOverflowError出现的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

java.lang.StackOverflowError出现的原因

严重: Exception initializing page context
java.lang.StackOverflowError
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:545)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)

StackOverflow  这个问题一般是程序里可能是有死循环或递归调用所产生的;可以查看一下程序,也可以增大JVM的内存

在Eclipse中JDK的配置中加上 -XX:MaxDirectMemorySize=128  就行了,默认是64M,增大一倍,还不行的话,就用256吧,

还不行的话,估计就是程序里头有死循环,或递归调用没写好了。

深入理解java.lang.StackOverflowError

StackOverflowError:栈溢出错误,如果一个线程所需用到栈的大小>配置允许最大的栈大小,那么jvm就会抛出StackOverflow。

栈的特点

1、栈,也叫栈内存,是jvm的内存模型之一,每当启动一个新线程的时候,jvm都会为它分配一个java栈。jvm只会直接对java栈执行两种操作,以帧为单位的压栈和出栈。

2、栈存储的内容:方法内的局部变量表、操作数、动态链接、方法出口信息、其他等信息。

  • 1)局部变量表:保存函数的参数以及局部变量用的,局部变量表中的变量只在当前函数调用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也会随之销毁。
  • 2)操作数:主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。在概念模型中,两个栈帧是相互独立的,但是大多数虚拟机的实现都会进行优化,令两个栈帧出现一部分重叠,令下面部分的操作数栈与上面部分的局部变量表重叠在一块,这样在方法调用的时候可以共用一部分数据,无需进行额外的参数复制传递。

  • 3)动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。在Class文件的常量池中存有大量的 符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候转化为直接引用,这种转化 称为静态解析。另外一部分将在每一次的运行期期间转化为直接引用,这部分称为动态连接。
  • 4)方法出口信息:在方法退出之前,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息,用来恢复它的上层方法的执行状态,方法出口信息获取分为正常退出和异常退出。正常退出通过pc计数器的值获取,异常退出通过异常处理器表确定返回地址。
  • 5)附加信息:虚拟机规范中允许具体的虚拟机实现增加一些规范中没有描述的信息到栈帧中,这部分信息取决于虚拟机的实现。

3、栈的生命周期:随着线程的创建而创建,线程的结束而消亡,释放内存,所以栈内存是私有的。

4、栈的存储方式:栈内存以栈帧(Stack Frame)为单位存储,栈帧是一个内存区块,是一个有关方法和运行期数据的数据集。当一个方法M1被调用的时候,就会产生一个栈帧S1,并被压入到栈中,M1方法又调用了M2方法,这个时候又产生栈帧S2也被压入栈,M2方法执行完毕后,S2栈帧先出栈,S1栈帧再出栈,遵循“先进后出”原则。

出现StackOverflowError的原因分析

一般出现这个问题是因为程序里有死循环或递归调用所产生的。

如:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //死循环
        int i=0;
        while (true){
            i++;
            Log.i("ruxing","i="+i);
        }
    }
    //递归
    private void add(int i){
        i++;
        Log.i("ruxing","i="+i);
        add(i);
    }
}

以递归为例,详解程序:

1)启动MainActivity,会创建一个线程,同时创建一个栈内存。

2)调用add()方法的时候,会对add()方法进行压栈操作,将add()运行期数据的数据集保存到栈帧中。

3)add()递归调用时,都会产生一个新的栈帧区块,这是就会连续的产生新的栈帧区块。

4)当栈内存超过系统配置的栈内存,就会出现java.lang.StackOverflowError异常。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring SseEmitter推送消息及常用方法

    Spring SseEmitter推送消息及常用方法

    SseEmitter 是 Spring Framework 提供的用于支持 Server-Sent Events(SSE)的类,它允许服务器端向客户端推送事件流,实现服务器到客户端的单向通信,这篇文章主要介绍了Spring SseEmitter推送消息,需要的朋友可以参考下
    2024-07-07
  • java循环删除List元素报错的原因分析与解决

    java循环删除List元素报错的原因分析与解决

    大家在工作中应该都会遇到从List集合中删除某一个或多个元素的业务场景,相信大家都会避开在循环里面删除元素,使用其他方式处理,这是为什么呢,下面小编就来和大家详细聊聊
    2023-11-11
  • JAVA List和Map切割工具详解

    JAVA List和Map切割工具详解

    这篇文章主要介绍了JAVA List和Map切割工具详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 完美解决idea创建文件时,文件不分级展示的情况

    完美解决idea创建文件时,文件不分级展示的情况

    这篇文章主要介绍了完美解决idea创建文件时,文件不分级展示的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • SpringBoot中的Redis 缓存问题及操作方法

    SpringBoot中的Redis 缓存问题及操作方法

    这篇文章主要介绍了SpringBoot中的Redis 缓存,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • 解决MyBatis中模糊搜索使用like匹配带%字符时失效问题

    解决MyBatis中模糊搜索使用like匹配带%字符时失效问题

    Mybatis是我们日常项目中经常使用的框架,在项目中我们一般会使用like查询作为模糊匹配字符进行搜索匹配,下面的Mapper.xml是我们使用like在项目中进行模糊匹配的常用方式,感兴趣的朋友跟随小编一起看看吧
    2021-09-09
  • java中int初始化可以为0,但不能为NULL问题

    java中int初始化可以为0,但不能为NULL问题

    这篇文章主要介绍了java中int初始化可以为0,但不能为NULL问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • mybatis入门_动力节点Java学院整理

    mybatis入门_动力节点Java学院整理

    这篇文章主要为大家详细介绍了mybatis入门的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • java使用hadoop实现关联商品统计

    java使用hadoop实现关联商品统计

    本篇文章java使用hadoop实现关联商品统计,可以实现商品的关联统计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-10-10
  • java判断字符串中是否包含中文并过滤中文

    java判断字符串中是否包含中文并过滤中文

    这篇文章主要为大家详细介绍了java判断字符串中是否包含中文,并过滤掉中文,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09

最新评论