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();
        }
    }

    参数设置如下:

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

  • 相关阅读:
    Docker搭建redis集群
    PHP中的OPCode和OPCache
    Redis的三种集群模式
    MySQL事务的隔离级别
    Docker镜像分层技术
    为什么 MongoDB 选择B树,Mysql 选择B+树?
    MongoDB的使用
    cesium+vue挖坑展示
    Ceium+Vue踩坑记录
    渲染总结——记录
  • 原文地址:https://www.cnblogs.com/java-spring/p/9854841.html
Copyright © 2011-2022 走看看