JVM--异常情况

堆相关的主要就是堆内存异常,不停的创建对象,并且存在应用指向,比如利用List容器存储下来。

/**
     * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump.hprof
     *
     * 堆内存溢出
     */
    @Test
    public void test01(){
        List<CustomerObj> lst=new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            lst.add(new CustomerObj());
        }
        System.out.println("run over");
    }

在d盘下生成文件,用D:\ProgramFiles\Java\jdk1.8.0_144\bin\jvisualvm.exe打开,在概要中显示具体的信息
在这里插入图片描述
发现CustomerObj实例数过多。
在这里插入图片描述

栈相关的异常主要就是栈容量无法容纳新创建的栈帧,比如调用栈过深, \color{#FF0000}{栈相关的异常主要就是栈容量无法容纳新创建的栈帧,比如调用栈过深,} 栈相关的异常主要就是栈容量无法容纳新创建的栈帧,比如调用栈过深,
或者方法中变量过多,执行方法时分配的栈帧需要更多的容量。 \color{#FF0000}{或者方法中变量过多,执行方法时分配的栈帧需要更多的容量。} 或者方法中变量过多,执行方法时分配的栈帧需要更多的容量。
肯定不会出现栈容量溢出的问题,因为线程开始执行,即为每一个线程分配了线程独享的栈内存 \color{#FF0000}{肯定不会出现栈容量溢出的问题,因为线程开始执行,即为每一个线程分配了线程独享的栈内存} 肯定不会出现栈容量溢出的问题,因为线程开始执行,即为每一个线程分配了线程独享的栈内存
方法调用过深导致的StackOverFlowError,往往就是使用到了递归。

    @Test
    public void test02(){
        stackLeaf();
    }

    public void stackLeaf(){
        stackLeaf();
    }

还有一种情况,在 32 位的系统上才能出现 u n a b l e t o c r e a t e n a t i v e t h r e a d , \color{#FF0000}{还有一种情况,在32位的系统上才能出现unable to create native thread,} 还有一种情况,在32位的系统上才能出现unabletocreatenativethread
因为 32 位机器给每个进程分配的最大空间才为 2 G ,导致没有 \color{#FF0000}{因为32位机器给每个进程分配的最大空间才为2G,导致没有} 因为32位机器给每个进程分配的最大空间才为2G,导致没有
空间为线程创建对应的栈空间 \color{#FF0000}{空间为线程创建对应的栈空间} 空间为线程创建对应的栈空间

方法区和运行常量池
1.7之前常量池在方法区中,1.7后在堆中

    /**
     * -Xmx20m
     * 
     * 常量池溢出
     */
    @Test
    public void test04(){
        String str="";
        List<String> lst=new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            str=str+i;
            lst.add(str.intern());
        }
        System.out.println("run over");
    }

在1.8中执行得到堆内存溢出。
在这里插入图片描述
方法区中存储的是类信息,比如类变量、方法,修饰符。如果采用动态代理的形式大量创建类,也会出现溢出,但是在1.8中不会出现。1.8后PermSize和MaxPermSize参数没有用了,因为已经去掉了永久代,改为元空间,

直接空间导致的内存溢出

    /**
     * Unsafe分配空间-导致直接内存OutOfMemory
     * @throws IllegalAccessException
     */
    @Test
    public void test06() throws IllegalAccessException {
        Field unsafeField= Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        while (true){
            unsafe.allocateMemory(1024*1024);
        }
    }

直接内存溢出和堆内存溢出最大的不同是如果发生了直接内存溢出,heap dump文件中将不会有什么明显的异常。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值