zoukankan      html  css  js  c++  java
  • JVM异常之:栈溢出StackOverflowError

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

    一、StackOverflowError(栈溢出)

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

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

    示例1:

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

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

    结果:

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

     示例2:

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

    结果:

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

    反编译代码:

    package com.dxz.jvm;
    
    public class StackOverFlow2
    {
      public static void main(String[] args)
      {
        StackOverFlow2 stackOverFlow2 = new StackOverFlow2();
        try
        {
          StackOverFlow2 tmp13_12 = stackOverFlow2; tmp13_12.getClass(); OneObject localOneObject = new OneObject();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    
      public class OneObject
      {
        OneObject oneObject = new OneObject(StackOverFlow2.this);
    
        public OneObject()
        {
        }
      }
    }

     看下命令行:

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

    当Stack满了就抛出error了。 所以才发生了上面的java.lang.StackOverflowError 溢出错误。
    注意:是递归的错误,才出现Stack满的情况,而无限循环一般不会占用更多的内存或者具体的Stack,只是占cpu而已,所以不会抛此错误。
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/duanxz/p/8515821.html
Copyright © 2011-2022 走看看