• 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();
            }
    
        }
    }
  • 相关阅读:
    配置PyDev,开始eclipsePython之旅
    PyDev下PyQt 的尝试
    逻辑回归 C++
    HP Unix vsftp服务配置
    线性回归(最小二乘法、批量梯度下降法、随机梯度下降法、局部加权线性回归) C++
    批量梯度下降(Batch gradient descent) C++
    利用expect验证主机口令
    python Paramiko 模块远程管理主机
    文件系统巡检
    awk查找特定字段
  • 原文地址:https://www.cnblogs.com/lvcai/p/13603282.html
Copyright © 2020-2023  润新知