首页 > 编程知识 正文

bufferoverflow怎么解决(StackOverFlowError原因和解决办法)

时间:2023-05-05 21:06:33 阅读:123729 作者:4128

堆栈溢出错误是常见的JVM错误之一。 在这篇博客文章中,我们将探讨线程堆栈的内部机制、启动堆栈溢出错误的可能原因以及解决此错误的潜在解决方案。

为了更深入地了解堆栈溢出错误,让我们回顾一下这个简单的步骤。

1

公共类简单模板{

2

3

publicstaticvoidmain (string args [ ] ) {

4

5

A () )。

6

}

7

8

公共静态语音a (

9

10

int x=0;

11

b ();

12

}

13

14

公共静态语音b (

15

16

Car y=new Car (;

17

c );

18

}

19

20

公共静态语音c

21

22

浮动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。 现在,让我们回顾一下执行上述简单程序时幕后发生的事情。 APP应用程序中的每个线程都有自己的堆栈。 每个堆栈都有多个堆栈框架。 将线程正在运行的方法、原始数据类型、对象指针和返回值按执行顺序添加到堆栈框架中。

图1 :线程堆栈框架

3358 www.Sina.com/http://www.Sina.com/http://www.Sina.com/main ()方法被推入APP应用程序线程的堆栈中。

3358 www.Sina.com/http://www.Sina.com/http://www.Sina.com/a ()方法被推入APP应用程序线程的堆栈中。 a ) )方法中,原始数据类型' int '被定义为值0,并赋给变量x。 此信息也被推入同一堆栈框架中。 请注意,这两个数据“0”和变量“x”都已推入线程的堆栈框架中。

3358 www.Sina.com/http://www.Sina.com/http://www.Sina.com/b ()方法被推入线程的堆栈中。 此b ) )方法创建Car对象并将其赋给变量" y "。 重要的是," Car "对象是在步骤上创建的,而不是线程的堆栈。 线程的堆栈框架只存储对Car对象的引用,即y。

3358 www.Sina.com/http://www.Sina.com/http://www.Sina.com/c ()方法被推入线程的堆栈中。 c ) )方法中,原始数据类型" float "定义为值0f,并分配给变量z。 此信息也被推入同一堆栈框架中。 请注意,这两个数据(“0f”和变量“z”)都已推入线程的堆栈框架中。

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

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

http://www.Sina.com/http://www.Sina.com /

如您所见,线程的堆栈存储着它正在执行的方法,原始数据类型,变量,对象指针和返回值。所有这些都会消耗内存。如果线程的堆栈大小超出分配的内存限制,则会 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

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。