JVM异常之:栈溢出*Error

时间:2023-03-08 23:35:29
JVM异常之:栈溢出*Error

  在java虚拟机规范中,虚拟机栈和本地方法栈都会出现*Error和OutofMemoryError,程序计数器是java虚拟机中唯一一块不会产生error的内存区域。

一、*Error(栈溢出)

*Error代表的是,当栈深度超过虚拟机分配给线程的栈大小时就会出现此error。

在eclipse中增加jvm参数见《eclipse调试时增加jvm参数

示例1:

package com.dxz.jvm;

/**
* @Described:栈层级不足
* @VM args:-Xss128k
*/
public class * {
private int i; public void plus() {
i++;
plus();
} public static void main(String[] args) {
* * = new *();
try {
*.plus();
} catch (Error e) {
System.out.println("Error:stack length:" + *.i);
e.printStackTrace();
}
}
}

-vm args-Xss128k  :说明后面是VM的参数,所以后面的其实都是JVM的参数了

结果:

Error:stack length:997
java.lang.*Error
at com.dxz.jvm.*.plus(*.java:11)

示例2:

package com.dxz.jvm;

/**
* @Described:递归Constructer
* @VM args:-Xss128k
*/
public class *2 { public class OneObject {
OneObject oneObject = new OneObject();
} public static void main(String[] args) {
*2 *2 = new *2();
try {
OneObject oneObject = *2.new OneObject();
} catch (Exception e) {
e.printStackTrace();
}
}
}

结果:

Exception in thread "main" java.lang.*Error
at com.dxz.jvm.*2$OneObject.<init>(*2.java:10)

反编译代码:

package com.dxz.jvm;

public class *2
{
public static void main(String[] args)
{
*2 *2 = new *2();
try
{
*2 tmp13_12 = *2; tmp13_12.getClass(); OneObject localOneObject = new OneObject();
} catch (Exception e) {
e.printStackTrace();
}
} public class OneObject
{
OneObject oneObject = new OneObject(*2.this); public OneObject()
{
}
}
}

看下命令行:

JVM异常之:栈溢出*Error

说明:在这里  constructer 中是调用 init , 而 static 是调用 cinit , 固我们如果将自己的对象放入到 static 中是不会造成递归的, 而如果将自己本身放到 constructer 中他就会不断的调用 init ,递归并不是马上返回,而是一层一层的保存在Stack里边,满足结束条件后才一层一层的返回。

当Stack满了就抛出error了。 所以才发生了上面的java.lang.*Error 溢出错误。
注意:是递归的错误,才出现Stack满的情况,而无限循环一般不会占用更多的内存或者具体的Stack,只是占cpu而已,所以不会抛此错误。