这篇文章我们介绍下jvm另外一种内存溢出,就是StackOverflowError,发生这个的问题主要是栈内存溢出,完整的错误实例如下:
Exception in thread "main" java.lang.StackOverflowError at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:675) at java.lang.StringBuilder.append(StringBuilder.java:214) at com.oom.demo.OomDemo.Demo1.stackTest(Demo1.java:8) at com.oom.demo.OomDemo.Demo1.stackTest(Demo1.java:10) at com.oom.demo.OomDemo.Demo1.stackTest(Demo1.java:10) at com.oom.demo.OomDemo.Demo1.stackTest(Demo1.java:10)
这个栈其实也有一部分内存存储,我们普及下栈的作用:
虚拟机栈(Java Virtual Machine Stack),早期也叫Java栈,每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。 虚拟机栈的作用:主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。 每个方法被执行的时候都会创建一个”栈帧”,用于存储局部变量表(包括参数)、操作栈、方法出口等信息。 每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。 栈帧(Stack Frame) 是用于虚拟机执行时方法调用和方法执行时的数据结构,它是虚拟栈的基本元素,栈帧由局部变量区、操作数栈等组成。 每一个方法从调用到方法返回都对应着一个栈帧入栈出栈的过程。最顶部的栈帧称为当前栈帧,栈帧所关联的方法称为当前方法,定义这个方法的类称为当前类,该线程中,虚拟机有且也只会对当前栈帧进行操作。 栈帧的作用有存储数据,部分过程结果,处理动态链接,方法返回值和异常分派。@哆啦 每一个栈帧包含的内容有局部变量表、操作数栈、动态链接、方法返回地址和一些额外的附加信息。在编译代码时,栈帧需要多大的局部变量表,多深的操作数栈都可以完全确定的,并写入到方法表的code属性中。
下面我们还是进行演示+解决
一、异常演示
演示的时候,完整代码如下:
package com.oom.demo.OomDemo; public class Demo1 { private int length = 1; public void stackTest() { System.out.println("Demo1 lenght=" + length); length++; stackTest(); } public static void main(String[] args) { Demo1 test = new Demo1(); test.stackTest(); } }
这里不需要做任何配置,直接默认即可,运行后可以看到如下的错误信息
二、异常解决
与栈相关的参数配置如下:
-Xss是指设定每个线程堆栈大小,在JDK1.5之前栈容量默认是256K,之后的默认大小是1M;
遇到栈相关异常的时候,根本原因如下:
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 如果虚拟机在扩展栈时无法申请到足够的内存,则将抛出OutOfMemmoryError异常。
所以基于上面的原因,解决的思路有如下两个:
1、修改代码,查看这里调用的深度,尽量减少这个深度。
2、通过设置-Xss,增加现成的堆栈大小。
还没有评论,来说两句吧...