JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace

直接上代码:

public class Test001 {
    public static void main(String[] args) {
        //java.lang.StackOverflowError   栈溢出错误, 这个是error 不是异常,因为StackOverflowError 是Error的子类
        // 栈溢出, 递归方法,调方法
        m1();
    }
    public static void m1(){
        m1();
    }
    @Test
    public void test02(){
        // java.lang.OutOfMemoryError: Java heap space  堆溢出 这个是error Error的子类
        // 堆溢出, 直接new 一个1G的大对象,就报异常了
        ArrayList<int[]> list = new ArrayList<>();
        while(true){
            int[] ints = new int[1024];
            list.add(ints);
        }
        //或者new 一个 大对象
        //Object[] objects = new Object[1024 * 1024 * 1024];
    }
}
class GC_OverHead_limit_demo1{
    public static void main(String[] args) {
        //jvm 参数设置: -Xms10m -Xmx10m -XX:+PrintGCDetails
        // java.lang.OutOfMemoryError: GC overhead limit exceeded
        // 这是错误
        // 出现的原因:  执行垃圾回收的时间占比太大,实际工作时间太小, 默认情况下 GC话费时间超过98% ,并且垃圾回收的内存少于2%, 就会抛出此错误
        int i = 0;
        List<String> list = new ArrayList<>();
        try {
            while (true){
                list.add(String.valueOf(++i).intern());
            }
        } catch (Exception e) {
            System.out.println(i);
            e.printStackTrace();
            throw e;
        }
    }
}


class Direct_buffer_memory_demo{
    private static final int BUFFER = 1024*1024*20; //20M
    public static void main(String[] args) {

        // 直接内存不属于 jvm 运行时数据区的一部分
        // 对象存储的位置,不在jvm的堆中,而是在物理内存中(直接内存中,为内存的1/4), 这样直接内存中的对象不停增加,直到满了,而此时jvm 的 gc并不会执行,所以报这个错误
        // java.lang.OutOfMemoryError: Direct buffer memory
        // 怎样查看直接内存大小  sun.misc.VM.maxDirectMemory() /1024/1024  单位 m

        // jvm 参数:设置堆最大为10m,  -Xms10m -Xmx10m -XX:+PrintGCDetails   可以设置直接内存,如果不设置 和堆空间最大值相同
        System.out.println(VM.maxDirectMemory() / 1024 / 1024);// 直接内存大小为 9m
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10 * 1024 * 1024);//这里直接放10m 的缓存
    }
}

class Unable_to_create_new_native_Thread_demo{
    public static void main(String[] args) throws InterruptedException {
        // 这个是高并发情况下 容易爆出的生产上的错误
        // java.lang.OutOfMemoryError: Unable_to_create_new_native_Thread
        // 一个应用进程里 创建了过个线程,直接撑爆最大上限, linux服务器默认普通用户一个进程创建线程上限为1024, 如果是root用户则无上限
        // 解决方案: 遇到这个错误,分析程序是否需要这么多线程,改代码,  或者修改服务器配置,增加创建线程上限
        // https://www.jianshu.com/p/103589cea5f5
        // https://blog.csdn.net/east4ming/article/details/80179670
        //这里模拟一个 main线程下 创建多个线程
        AtomicInteger count = new AtomicInteger();
        while(true){
            new Thread(()->{
                try {
                    count.getAndIncrement();
                    System.out.println(count.get());
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        //这个在win系统下 并没有测出错误结果,  在linux系统下 930多个就报错误了
    }
}

class MetaSpace_demo1{
    static class OOM_Test{
        //静态内部类
    }
    public static void main(String[] args) {
        // 1.8之后,元空间取代了 永久代,  且元空间不在 jvm的 运行时数据区,而是使用的本地内存
        // jvm参数: -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=10m
        // 运行结果: 396 时候就报错误了;    java.lang.OutOfMemoryError: Metaspace
        /**
         *  元空间 存放的信息:
         *  1: 虚拟机加载的类信息
         *  2: 常量池
         *  3: 静态变量
         *  4: 即使编译后的代码
         *
         *  所以: 不停地创建 静态类,存放到元空间,直到撑爆,报异常
         */
        int i = 0;
        try {
            while(true){
                i++;
                //这里使用 cglib 生成代理类, 这个类是静态的,所以创建后放在元空间
                //1, 创建工具类
                Enhancer enhancer = new Enhancer();
                //2, 设置父类
                enhancer.setSuperclass(OOM_Test.class);
                enhancer.setUseCache(false);//不使用缓存
                //3, 设置回调函数
                enhancer.setCallback(new MethodInterceptor(){
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        return methodProxy.invokeSuper(o,args);
                    }
                });
                //4, 创建代理对象
                Object o = enhancer.create();
            }
        } catch (Exception e) {
            System.out.println(i);
            e.printStackTrace();
        }

    }
}
原文地址:https://www.cnblogs.com/lvcai/p/13603282.html