zoukankan      html  css  js  c++  java
  • java面试-谈谈你对OOM的理解

    1、java.lang.StackOverflowError

    • 在一个函数中调用自己就会产生这样的错误(栈溢出)
    • 发生区域:java虚拟机栈或本地方法栈
    public class StackOverFlowErrorDemo {
        public static void main(String[] args) {
            stackOverFlowError();
        }
    
        public static void stackOverFlowError(){
            stackOverFlowError();
        }
    }
    

    2、java.lang.OutOfMemoryError: Java heap space

    • new 一个很大对象
    • 发生区域:java堆
    /**
     * -Xms10m -Xmx10m
     */
    public class JavaHeapSpaceDemo {
    
        static class  OOMObject{
        }
    
        public static void main(String[] args) {
            List<OOMObject> list = new ArrayList<>();
            while (true){
                list.add(new OOMObject());
            }
        }
    }
    

    3、java.lang.OutOfMemoryError: GC overhead limit exceeded

    • GC回收时间过长,超过98%的时间用来做GC,并且回收了不到2%的堆内存
    /**
     * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
     */
    public class GCoverheadDemo {
    
        public static void main(String[] args) {
            int i = 0;
            List<String> list = new ArrayList<>();
    
            while (true) {
                list.add(String.valueOf(++i).intern());
            }
        }
    }  

    4、java.lang.OutOfMemoryError: Direct buffer memory

    原因:直接内存不足

    写NIO程序经常使用ByteBuffer来读取或写入数据,这是一种基于通道与缓冲区的I/O方式

    ByteBuffer.allocate() 分配JVM堆内存,属于GC管辖范围,需要拷贝所以速度相对较慢

    ByteBuffer.allocateDirect() 分配操作系统本地内存,不属于GC管辖范围,不需要内存拷贝所以速度相对较快

    /**
     * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
     */
    public class DirectBufferMemoryDemo {
    
        public static void main(String[] args) throws InterruptedException {
            System.out.println("maxDirectMemory : " + sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB");
            TimeUnit.SECONDS.sleep(1);
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
        }
    }
    

    5、java.lang.OutOfMemoryError : unable to create new native thread

    • 一个应用进程创建了多个线程,超过系统承载极限,Linux默认允许单个进程可以创建的线程数1024
    /**
     * 一个应用进程创建了多个线程,超过系统承载极限,Linux默认是1024
     */
    public class UnableCreateNewThreadDemo {
        public static void main(String[] args) {
            for (int i = 0; ; i++) {
                new Thread(() -> {
                    try {
                        Thread.sleep(Integer.MAX_VALUE);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }, String.valueOf(i)).start();
            }
        }
    }  

    linux系统下:

    ulimit -u  --查看线程上限
    cat /etc/security/limits.d/20-nproc.conf 
    

    6、java.lang.OutOfMemoryError: Metaspace

    java8使用Metaspace代替永久代,与永久代最大的区别是:元空间并不在虚拟机内存中,而是使用本地内存。  

    永久代(java8使用Metaspace)存放的信息:

    • 虚拟机加载的类信息
    • 常量池
    • 静态变量
    • 即时编译后的代码
    /**
     * 不断生成类往元空间推,类占据的空间总是会超过Metaspace的大小
     * -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m
     */
    public class MetaspaceOOMDemo {
    
        static class OOMTest {
        }
    
        public static void main(String[] args) {
            int i = 0; //模拟计数多少次后发生了异常
            try {
                while (true) {
                    i++;
                    Enhancer enhancer = new Enhancer();
                    enhancer.setSuperclass(OOMTest.class);
                    enhancer.setUseCache(false);
                    enhancer.setCallback(new MethodInterceptor() {
                        @Override
                        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                            return methodProxy.invokeSuper(o, args);
                        }
                    });
                    enhancer.create();
                }
            } catch (Throwable e) {
                System.out.println(i + "次后发送了异常");
                e.printStackTrace();
            }
    
        }
    }
    

      

      

  • 相关阅读:
    Linux下安装配置SVN服务器,windows访问
    Zookeeper集群版搭建
    Zookeeper单机版启动
    Nginx-Session缓存一致性-memcached
    Nginx-配置多台Tomcat-反向代理
    Linux-tomcat-安装启动
    Linux-JDK-环境搭建安装
    Nginx-安装-运行访问页面
    Linux-虚拟机-克隆-学习
    解决CocosCreator 在微信小游戏中使用Socket.io 报错的问题
  • 原文地址:https://www.cnblogs.com/wjh123/p/11143379.html
Copyright © 2011-2022 走看看