在java虚拟机规范中,虚拟机栈和本地方法栈都会出现StackOverflowError和OutofMemoryError,程序计数器是java虚拟机中唯一一块不会产生error的内存区域。
一、StackOverflowError(栈溢出)
StackOverflowError代表的是,当栈深度超过虚拟机分配给线程的栈大小时就会出现此error。
在eclipse中增加jvm参数见《eclipse调试时增加jvm参数》
示例1:
packagecom.dxz.jvm;/*** @Described:栈层级不足
* @VM args:-Xss128k*/
public classStackOverFlow {private inti;public voidplus() {
i++;
plus();
}public static voidmain(String[] args) {
StackOverFlow stackOverFlow= newStackOverFlow();try{
stackOverFlow.plus();
}catch(Error e) {
System.out.println("Error:stack length:" +stackOverFlow.i);
e.printStackTrace();
}
}
}
-vm args-Xss128k :说明后面是VM的参数,所以后面的其实都是JVM的参数了
结果:
Error:stack length:997java.lang.StackOverflowError
at com.dxz.jvm.StackOverFlow.plus(StackOverFlow.java:11)
示例2:
packagecom.dxz.jvm;/*** @Described:递归Constructer
* @VM args:-Xss128k*/
public classStackOverFlow2 {public classOneObject {
OneObject oneObject= newOneObject();
}public static voidmain(String[] args) {
StackOverFlow2 stackOverFlow2= newStackOverFlow2();try{
OneObject oneObject= stackOverFlow2.newOneObject();
}catch(Exception e) {
e.printStackTrace();
}
}
}
结果:
Exception in thread "main"java.lang.StackOverflowError
at com.dxz.jvm.StackOverFlow2$OneObject.(StackOverFlow2.java:10)
反编译代码:
packagecom.dxz.jvm;public classStackOverFlow2
{public static voidmain(String[] args)
{
StackOverFlow2 stackOverFlow2= newStackOverFlow2();try{
StackOverFlow2 tmp13_12= stackOverFlow2; tmp13_12.getClass(); OneObject localOneObject = newOneObject();
}catch(Exception e) {
e.printStackTrace();
}
}public classOneObject
{
OneObject oneObject= new OneObject(StackOverFlow2.this);publicOneObject()
{
}
}
}
看下命令行:
说明:在这里 constructer 中是调用 init , 而 static 是调用 cinit , 固我们如果将自己的对象放入到 static 中是不会造成递归的, 而如果将自己本身放到 constructer 中他就会不断的调用 init ,递归并不是马上返回,而是一层一层的保存在Stack里边,满足结束条件后才一层一层的返回。
当Stack满了就抛出error了。 所以才发生了上面的java.lang.StackOverflowError 溢出错误。
注意:是递归的错误,才出现Stack满的情况,而无限循环一般不会占用更多的内存或者具体的Stack,只是占cpu而已,所以不会抛此错误。