转载自:https://blog.csdn.net/qq_31615049/article/details/82980799
一、 栈溢出(StackOverflowError)
栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口灯信息。局部变量表又包含基本数据类型,对象引用类型(局部变量表编译器完成,运行期间不会变化)
所以我们可以理解为栈溢出就是方法执行是创建的栈帧请求的深度超过了栈能给予的最大深度。
最有可能的就是:方法递归调用产生这种结果。
public class JvmDemo {
private int i = 0;
public void a(){
System.out.println(i++);
a();
}
public static void main(String[] args) {
JvmDemo j = new JvmDemo();
j.a();
}
}
如何解决:
我们需要使用参数 -Xss 去调整JVM栈的大小
解决后效果如下
但是需要注意递归程序的风险
。
二、 堆溢出(OutOfMemoryError:java heap space)
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的情况中会出现永久带溢出的现象。