一、 栈溢出(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的情况中会出现永久带溢出的现象。

 

技术
©2019-2020 Toolsou All rights reserved,
Python代码编写原则及技巧Linux gcc自带检测内存泄漏工具asanJAVA Future类的使用pychrom激活码 idea实现protobuf的.proto文件编译成.java文件教程Qt怎样禁止用户最大化窗口解决办法ShellCode —— 无线程注入opencv——基于SVM的数字识别(2)docker中的redisDS5解决 内存踩踏