zoukankan      html  css  js  c++  java
  • OutOfMemoryError/OOM/内存溢出异常实例分析--虚拟机栈和本地方法栈溢出

    关于虚拟机栈和本地方法栈,在JVM规范中描述了两种异常:

    1.如果线程请求的栈深度大于JVM所允许的深度,将抛出StackOverflowError异常;

    2.如果虚拟机在扩展栈时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    下面进行虚拟机栈和本地方法栈的SOF异常测试:

    public class JavaVMStackSOF {
    
        private int stackLenth = 1;
    
        public void stackLeak() {
            stackLenth++;
            stackLeak();
        }
    
        public static void main(String[] args) throws Throwable{
            JavaVMStackSOF oom = new JavaVMStackSOF();
            try {
                oom.stackLeak();
            } catch (Throwable e) {
                System.out.println("栈深度:" + oom.stackLenth);
                throw e;
            }
        }
    }

    运行时设置栈容量为:-Xss128k

    具体操作可参照:OutOfMemoryError/OOM/内存溢出异常实例分析--堆内存溢出

    运行结果如下:

    实验结果表明:在单线程下,无论是 由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机栈跑出的都是StackOverflowError异常。

    怎么产生OOM异常呢?

    可以通过不断创建线程的方法,在这种情况下,为每个线程分配的内存越大,就会越容易产生OOM异常。

    下面在测试之前,先特别提示一下,如果想测试栈的OOM异常,记得先保存当前的工作。由于Windows平台的虚拟机中,Java的线程是映射到操作

    系统的内核上的,因此以下代码可能会导致操作系统假死

    public class JavaVMStackOOM {
    
        private void dontStop() {
            while (true) {
            }
        }
    
        public void stackLeakByThread() {
            while (true) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        dontStop();
                    }
                }).start();
            }
        }
    
        public static void main(String[] args) {
            JavaVMStackOOM oom = new JavaVMStackOOM();
            oom.stackLeakByThread();
        }
    }

    参数设置如下:

    我测了一下,系统差点卡死,就不展示测试结果了

  • 相关阅读:
    MySQL 练习题
    MySQL 增删查改
    HTML显示与隐藏
    360布局
    div布局
    HTML练习2
    HTML练习

    if语句的用法及其案例
    输入输出,数据类型与运算符
  • 原文地址:https://www.cnblogs.com/java-spring/p/9854841.html
Copyright © 2011-2022 走看看