什么情况下会发生堆内存溢出,栈内存溢出,结合实例说明

、 栈溢出(StackOverflowError)

栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口灯信息。局部变量表又包含基本数据类型,对象引用类型(局部变量表编译器完成,运行期间不会变化)

所以我们可以理解为栈溢出就是方法执行是创建的栈帧超过了栈的深度。那么最有可能的就是方法递归调用产生这种结果。

public class JvmTest {

private int i = 0;

public void a(){

System.out.println(i++);

a();

}

public static void main(String[] args) {

JvmTest j = new JvmTest();

j.a();

}

}

输出结果:


如何解决:

我们需要使用参数 -Xss 去调整JVM栈的大小


解决后效果如下


但是需要注意递归程序的风险。

二、 堆溢出(OutOfMemoryError:java heap space)

heap space表示堆空间,堆中主要存储的是对象。如果不断的new对象则会导致堆中的空间溢出

public class JvmTest {

public static void main(String[] args) {

List<String> aList = new ArrayList<String>();

try{

while(true){

aList.add("asdasdasdas");

}

}catch(Throwable e){

System.out.println(aList.size());

e.printStackTrace();

}

}

}

异常信息:


可以通过 -Xmx4096M 调整堆的总大小

三、 永久代溢出(OutOfMemoryError: PermGen space)

由于JDK7、8移除永久带,所以上述代码在JDK1.6的情况中会出现永久带溢出的现象。


---------------------

作者:LJHSkyWalker