StackOverFlowError原因和解决办法
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
}
该程序非常简单,具有以下执行代码:
- main() 首先调用方法
- main() 方法调用 a() 方法。在a() 方法内部 ,整数变量“ x”被初始化为值0。
- a() 方法反过来调用 b() 方法。在b() 方法内部 ,构造了Car对象并将其分配给变量“ y”。
- 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)
图3:StackOverflowError进度
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原因和解决办法相关推荐
- java 内存 溢出_java内存溢出的几种原因和解决办法是什么?
java内存溢出的几种原因和解决办法是什么? java内存溢出的几种原因和解决办法是: 第一类内存溢出,也是大家认为最多,第一反应认为是的内存溢出,就是堆栈溢出: 那什么样的情况就是堆栈溢出呢?当你看 ...
- oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...
[案例]Oracle等待事件library cache lock产生原因和解决办法 时间:2016-12-07 18:56 来源:Oracle研究中心 作者:网络 点击: 次 天萃荷净 O ...
- 服务器越来越慢的原因及解决办法
随着各种主机产品的推出,服务器出现的问题各式各样,由于虚拟主机都是同时运行,便会对服务器产生过大的压力,从而导致服务器的速度越来越缓慢,下面和大家分享一下服务器越来越慢的原因及解决办法. 1.虚拟主机 ...
- iis 无法连接mysql_远程无法连接SQL2000及MySQL的原因和解决办法
远程无法连接SQL2000及MySQL的原因和解决办法 时间:2019-11-10 11:06 1. 没有在数据库管理面板中设置远程连接IP造成的. 说明:为了提高操作系统的安全性,所有使用了星外安全 ...
- com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法
转自:https://blog.csdn.net/shinchan_/article/details/37818927 com/opensymphony/xwork2/spring/SpringObj ...
- 欠拟合的原因以及解决办法(深度学习)
之前这篇文章,我分析了一下深度学习中,模型过拟合的主要原因以及解决办法: 过拟合的原因以及解决办法(深度学习)_大黄的博客-CSDN博客 这篇文章中写一下深度学习中,模型欠拟合的原因以及一些常见的解决 ...
- android qq三方登录授权失败,QQ第三方登陆授权失败110401原因及解决办法分享
qq第三方登陆授权失败出现代码110401是什么情况?遇到这种情况该如何解决?相信很多用户们在操作的时候都出现过类似的情况吧?下面是小编带来的攻略解析,一起来关注下! qq第三方登陆授权失败11040 ...
- SyntaxError: invalid syntax的问题原因和解决办法
写在这里的初衷,一是备忘,二是希望得到高人指点,三是希望能遇到志同道合的朋友. 目录 一.问题 二.原因及解决办法 一.问题 // An highlighted block SyntaxError: ...
- mysql sleep详解_mysql sleep链接过多的原因及解决办法
今天收到运维同事短信,说有个线上业务"可能是数据库DB堵塞了,导致mysql链接过多,让我看一下". 回家后赶紧用家里vpn登录数据库服务器,show processlist 看了 ...
最新文章
- VSTO之旅系列(一):VSTO入门
- 网络经济与企业管理(第 2 章:企业战略管理)
- 计算机专业能评电子工程师吗,计算机工程师职称 评定条件
- java中接口可以产生数组吗,java接口Array介绍
- [转]更改windows 2003远程桌面连接的端口
- RHEL7体验KVM虚拟机
- Julia: 关于... (三个圆点)
- PayPal如何提现,PayPal提现手续费是多少?
- 手机浏览器哪家强,这3款口碑极佳的浏览器值得一用
- 有限公司清算组成员怎样构成
- java实现简单窗口小游戏“扫雷”
- PL/SQL将电话号码前三位用括号括起来(以XXX-XXX-XXXX为例)
- ros执行ctrl+c后修改程序运行时间
- 35岁以前成功的12条黄金法则[ZT]
- DDR2学习笔记(1)
- 关于 android 6.0 上的 nuplayer 播放时的图像卡顿
- 什么是网络霸屏营销,霸屏营销要怎么做?
- js给按钮增加快捷键功能(全)
- 2021年中国呼吸机相关性肺炎(VAP)市场趋势报告、技术动态创新及2027年市场预测
- Java面试的战地笔记