StackOverFlowError是常见的JVM错误之一。在此博客文章中,我们将研究线程堆栈的内部机制,可能触发StackOverFlowError的原因以及解决此错误的潜在解决方案。

为了更深入地了解StackOverFlowError,让我们回顾一下这个简单的程序:

1
public class SimpleExample {
2

3
      public static void main(String args[]) {
4

5
            a()
6
      }
7

8
      public static void a() {
9

10
            int x = 0;
11
            b();
12
      }
13

14
      public static void b() {
15

16
            Car y = new Car();
17
            c();
18
      }
19

20
      public static void c() {
21

22
            float z = 0f;
23
      System.out.println("Hello");
24
      }
25
}

该程序非常简单,具有以下执行代码:

  1. main() 首先调用方法
  2. main() 方法调用 a()  方法。在a() 方法内部 ,整数变量“ x”被初始化为值0。
  3. a() 方法反过来调用 b() 方法。在b() 方法内部 ,构造了Car对象并将其分配给变量“ y”。
  4. b() 方法反过来调用该 c() 方法。在c() 方法内部 ,浮点变量“ z”被初始化为值0。

现在,让我们回顾一下执行上述简单程序时幕后发生的事情。应用程序中的每个线程都有其自己的堆栈。每个堆栈都有多个堆栈帧。线程按执行顺序将其正在执行的方法,原始数据类型,对象指针和返回值添加到其堆栈帧中。

1:线程的堆栈框架

步骤#1 main() 方法被推入应用程序线程的堆栈中。

步骤#2 a() 方法被推入应用程序线程的堆栈中。在 a() 方法中,原始数据类型'int'定义为值0,并分配给变量x。该信息也被推入相同的堆栈框架中。请注意,两个数据(即“ 0”和变量“ x”)都被压入线程的堆栈框架中。

步骤#3 b() 方法被推入线程的堆栈。在该 b() 方法中,将创建Car对象并将其分配给变量“ y”。这里要注意的关键点是,“ Car”对象是在堆中创建的,而不是在线程的堆栈中创建的。只有Car对象的引用(即y)存储在线程的堆栈框架中。

步骤#4 c() 方法被推入线程的堆栈。在 c() 方法中,原始数据类型“ float”定义为值0f并分配给变量z。此信息也被推入相同的堆栈框架。请注意,两个数据(即“ 0f”和变量“ z”)都被压入线程的堆栈框架中。

一旦每个方法的执行完成,就将方法和变量/对象指针存储在堆栈帧中,如图2所示。

2:执行方法后的线程堆栈框架

是什么导致StackOverflowError

如您所见,线程的堆栈存储着它正在执行的方法,原始数据类型,变量,对象指针和返回值。所有这些都会消耗内存。如果线程的堆栈大小超出分配的内存限制,则会 StackOverflowError 抛出该错误。让我们看一下下面的bug程序,它会导致  StackOverflowError:

1
public class SOFDemo {
2

3
         public static void a() {
4

5
                  // Buggy line. It will cause method a() to be called infinite number of times.
6
                  a();
7
         }
8

9
         public static void main(String args[]) {
10

11
                   a();
12
         }
13
}

在此程序中, main() 方法调用 a()  方法。 a() 方法递归调用自身。此实现将导致  a() 方法被无限次调用。在这种情况下, a() 方法将无限次添加到线程的堆栈帧中。因此,经过数千次迭代后,将超出线程的堆栈大小限制。一旦超过堆栈大小限制,将导致  StackOverflowError:

1
Exception in thread "main" java.lang.StackOverflowError
2
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
3
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
4
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
5
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
6
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
7
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
8
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)
9
       at com.buggyapp.stackoverflow.SOFDemo.a(SOFDemo.java:7)

3StackOverflowError进度

StackOverflowError有什么解决方案?

有两种策略可以解决  StackOverflowError。

1.修改代码

由于进行了非终止的递归调用(如上例所示),因此线程堆栈大小可能会增大到较大的大小。在这种情况下,您必须修复导致递归循环的源代码。引发“ StackOverflowError”时,它将打印递归执行的代码的堆栈跟踪。此代码是开始调试和解决问题的良好指针。在上面的示例中,它就是 a()  方法。

2.增加线程堆栈大小(-Xss

可能有正当理由需要增加线程堆栈大小。也许线程必须执行大量方法或很多局部变量/已在执行线程的方法中创建?在这种情况下,可以使用JVM参数'-Xss。'增加线程的堆栈大小。启动应用程序时需要传递此参数。

1个

- Xss2m

这会将线程的堆栈大小设置为2 mb。

可能会带来一个问题:默认线程的堆栈大小是多少?默认线程堆栈大小根据您的操作系统,Java版本和供应商而异。

JVM版本

线程堆栈大小

Sparc 32位JVM

512k

Sparc 64位JVM

1024k

x86 Solaris / Linux 32位JVM

320K

x86 Solaris / Linux 64位JVM

1024K

Windows 32位JVM

320K

Windows 64位JVM

1024K

StackOverFlowError原因和解决办法相关推荐

  1. java 内存 溢出_java内存溢出的几种原因和解决办法是什么?

    java内存溢出的几种原因和解决办法是什么? java内存溢出的几种原因和解决办法是: 第一类内存溢出,也是大家认为最多,第一反应认为是的内存溢出,就是堆栈溢出: 那什么样的情况就是堆栈溢出呢?当你看 ...

  2. oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...

    [案例]Oracle等待事件library cache lock产生原因和解决办法 时间:2016-12-07 18:56   来源:Oracle研究中心   作者:网络   点击: 次 天萃荷净 O ...

  3. 服务器越来越慢的原因及解决办法

    随着各种主机产品的推出,服务器出现的问题各式各样,由于虚拟主机都是同时运行,便会对服务器产生过大的压力,从而导致服务器的速度越来越缓慢,下面和大家分享一下服务器越来越慢的原因及解决办法. 1.虚拟主机 ...

  4. iis 无法连接mysql_远程无法连接SQL2000及MySQL的原因和解决办法

    远程无法连接SQL2000及MySQL的原因和解决办法 时间:2019-11-10 11:06 1. 没有在数据库管理面板中设置远程连接IP造成的. 说明:为了提高操作系统的安全性,所有使用了星外安全 ...

  5. com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法

    转自:https://blog.csdn.net/shinchan_/article/details/37818927 com/opensymphony/xwork2/spring/SpringObj ...

  6. 欠拟合的原因以及解决办法(深度学习)

    之前这篇文章,我分析了一下深度学习中,模型过拟合的主要原因以及解决办法: 过拟合的原因以及解决办法(深度学习)_大黄的博客-CSDN博客 这篇文章中写一下深度学习中,模型欠拟合的原因以及一些常见的解决 ...

  7. android qq三方登录授权失败,QQ第三方登陆授权失败110401原因及解决办法分享

    qq第三方登陆授权失败出现代码110401是什么情况?遇到这种情况该如何解决?相信很多用户们在操作的时候都出现过类似的情况吧?下面是小编带来的攻略解析,一起来关注下! qq第三方登陆授权失败11040 ...

  8. SyntaxError: invalid syntax的问题原因和解决办法

    写在这里的初衷,一是备忘,二是希望得到高人指点,三是希望能遇到志同道合的朋友. 目录 一.问题 二.原因及解决办法 一.问题 // An highlighted block SyntaxError: ...

  9. mysql sleep详解_mysql sleep链接过多的原因及解决办法

    今天收到运维同事短信,说有个线上业务"可能是数据库DB堵塞了,导致mysql链接过多,让我看一下". 回家后赶紧用家里vpn登录数据库服务器,show processlist 看了 ...

最新文章

  1. VSTO之旅系列(一):VSTO入门
  2. 网络经济与企业管理(第 2 章:企业战略管理)
  3. 计算机专业能评电子工程师吗,计算机工程师职称 评定条件
  4. java中接口可以产生数组吗,java接口Array介绍
  5. [转]更改windows 2003远程桌面连接的端口
  6. RHEL7体验KVM虚拟机
  7. Julia: 关于... (三个圆点)
  8. PayPal如何提现,PayPal提现手续费是多少?
  9. 手机浏览器哪家强,这3款口碑极佳的浏览器值得一用
  10. 有限公司清算组成员怎样构成
  11. java实现简单窗口小游戏“扫雷”
  12. PL/SQL将电话号码前三位用括号括起来(以XXX-XXX-XXXX为例)
  13. ros执行ctrl+c后修改程序运行时间
  14. 35岁以前成功的12条黄金法则[ZT]
  15. DDR2学习笔记(1)
  16. 关于 android 6.0 上的 nuplayer 播放时的图像卡顿
  17. 什么是网络霸屏营销,霸屏营销要怎么做?
  18. js给按钮增加快捷键功能(全)
  19. 2021年中国呼吸机相关性肺炎(VAP)市场趋势报告、技术动态创新及2027年市场预测
  20. Java面试的战地笔记

热门文章

  1. 头歌 python 绘制人脸与人眼区域
  2. contes 打开端口
  3. Space Elevator 太空电梯(洛谷)
  4. Kali Linux 2021.1 详细安装教程
  5. 三国塔防游戏android源码
  6. ajax概述原理,ajax基本原理及步骤
  7. Java的Static关键字的作用
  8. MySQL MHA高可用
  9. 【数据结构Note4】-串、数组和广义表(kmp算法详解)
  10. Unity3D 开发工具系列 UI框架:定义设置Defines