很多朋友对于over flow观看免费观看和StackOverFlowError的原因和解决方案不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!
StackOverFlowError是常见的JVM错误之一。在这篇文章中,我将带大家了解线程堆栈的内部机制、触发StackOverFlowError的原因以及解决此错误的潜在解决方案。
首先先看一下下面这个简单的程序:
publicclassSimpleExample{npublicstaticvoidmain(Stringargs[]){na()n}npublicstaticvoida(){nintx=0;nb();n}npublicstaticvoidb(){nCary=newCar();nc();n}npublicstaticvoidc(){nfloatz=0f;nSystem.out.println("Hello");n}n}
这个程序非常简单,执行代码如下:
首先执行main()方法,main方法调用a()方法,a()方法里初始化一个变量x=0a()方法在调用b()方法。在b()方法内,构造Car对象并将其分配给变量yb()方法依次调用c()方法。在c()方法中,浮点变量z被初始化为值0现在,让我们看看执行上述简单程序时底层发生的情况。应用程序中的每个线程都有自己的堆栈。每个堆栈有多个堆栈帧。线程将其正在执行的方法、原始数据类型、对象指针以及返回值按照它们执行的顺序添加到其堆栈帧中。
线程栈帧
step1:main()方法被推入应用程序线程的堆栈中。
step2:a()方法被推入应用程序线程的堆栈中。在a()方法中,原始数据类型“int”定义为值0并分配给变量x。该信息也被推送到同一堆栈帧中。请注意,这两个数据(即“0”和变量“x”)都被推入线程的堆栈帧中。
step3:b()方法被推入线程的堆栈中。在b()方法中,创建Car对象并将其分配给变量“y”。这里需要注意的一个关键点是“Car”对象是在堆中创建的,而不是在线程的堆栈中创建的。只有Car对象的引用(即y)存储在线程的堆栈帧中。
step4:c()方法被推入线程的堆栈中。在c()方法中,原始数据类型“float”被定义为值0f并分配给变量z。该信息也被推送到同一堆栈帧中。请注意,这两个数据(即“0f”和变量“z”)都被推入线程的堆栈帧中。
每个方法执行完成后,该方法和存储在堆栈帧中的变量/对象指针将被删除。结果如下图
线程栈帧
为什么会导致StackOverFlowError?正如上面所分析的,线程的堆栈存储它正在执行的方法、原始数据类型、变量、对象指针和返回值。所有这些都会消耗内存。如果线程的堆栈大小超出了分配的内存限制,则会引发StackOverflowError。
让我们看一下下面的错误程序
publicclassDemo{npublicstaticvoida(){n//无限递归na();n}npublicstaticvoidmain(Stringargs[]){na();n}n}
在此程序中,main()方法调用a()方法。a()方法无限递归调用自身。这将导致a()方法被无限次调用。在这种情况下,a()方法将被无限次添加到线程的堆栈帧中。
因此,经过几千次迭代后,将超出线程的堆栈大小限制。一旦超出堆栈大小限制,就会导致StackOverflowError:
Exceptioninthread"main"java.lang.StackOverflowErrorntatcom.zxy.demo.test.Demo.a(Demo.java:8)ntatcom.zxy.demo.test.Demo.a(Demo.java:8)ntatcom.zxy.demo.test.Demo.a(Demo.java:8)ntatcom.zxy.demo.test.Demo.a(Demo.java:8)ntatcom.zxy.demo.test.Demo.a(Demo.java:8)ntatcom.zxy.demo.test.Demo.a(Demo.java:8)n怎么解决StackOverFlowError?
有几种方法可以解决StackOverflowError。
1.修复代码
由于没有终止的递归调用(如上例所示),线程堆栈大小可能会增长到很大。在这些情况下,您必须修复导致递归循环的源代码。当抛出StackOverflowError时,它将打印递归执行的代码的堆栈跟踪。
此代码是开始调试和解决问题的良好指针。在上面的示例中,它是a()方法。
2.增加线程堆栈大小(-Xss)
需要增加线程的堆栈大小可能有合理的原因。也许线程必须执行大量方法,或者线程正在执行的方法中/创建的大量局部变量。在这种情况下,我们可以使用JVM参数:-Xss来增加线程的堆栈大小。启动应用程序时需要传递此参数。
例子:-Xss2m
这会将线程的堆栈大小设置为2mb。这里可能会有一个问题:默认线程的堆栈大小是多少?默认线程堆栈大小因操作系统、Java版本和供应商而异。
JVMversion
Threadstacksize
Sparc32-bitJVM
512k
Sparc64-bitJVM
1024k
x86Solaris/Linux32-bitJVM
320K
x86Solaris/Linux64-bitJVM
1024K
Windows32-bitJVM
320K
Windows64-bitJVM
1024K
3.使用具有自定义堆栈大小的线程
解决StackOverflowError的另一种方法是利用Java的线程构造函数,它允许您为各个线程指定自定义堆栈大小。这个构造函数可以在Java文档中找到。虽然此选项可以灵活地为每个线程设置特定的堆栈大小,但需要注意的是,其有效性可能会因平台的不同而有所不同。
Threadthread=newThread(null,runnable,"CustomThread",customStackSize);nthread.start();
我们要意识到设置stackSize参数的影响可能不会在所有平台上保持一致。Java文档指出:“在某些平台上,stackSize参数的值可能没有任何影响。虚拟机可以自由地将stackSize参数视?为建议。”在之前的测试中,我们发现使用自定义堆栈大小调用此构造函数对Windows和某些其他平台没有影响。跨平台缺乏一致性使得该选项作为通用解决方案不太可靠。作为最佳实践,建议选择在所有平台上一致工作的解决方案,以确保应用程序的稳定性和可靠性。
关于over flow观看免费观看,StackOverFlowError的原因和解决方案的介绍到此结束,希望对大家有所帮助。
还没有评论,来说两句吧...