美文网首页
对于OOM的理解

对于OOM的理解

作者: 倚仗听江 | 来源:发表于2020-09-05 16:11 被阅读0次

OOM,即OutOfMemory,内存溢出

  1. OOM之 Java heap space
    java堆内存溢出,一般由于内存泄漏或者堆内存大小设置不当引起
String str = "sherlock";
        while (true) {
            str += new Random(100000).nextInt() + new Random(20000000).nextInt();
            str.intern();
        }
byte[] b = new byte[80 * 1024 * 1024];
  1. OOM之GC overhead limit
    GC回收时间过长,过长的定义是:超过98%的时间用来做GC并且回收了不到2%的堆内存,连续多次GC都只回收了不到2%的堆内存的极端情况才会抛出。
    本质是一个预判性的异常,抛出该异常时系统没有真正的内存溢出。是由于垃圾回收效果不明显,或者垃圾回收效率不如分配效率高引起的。
public static void main(String args[]) throws Exception {
        Map map = System.getProperties();
        Random r = new Random();
        while (true) {
            map.put(r.nextInt(), "value");
        }
    }

https://plumbr.io/outofmemoryerror/gc-overhead-limit-exceeded

  1. OOM之Direct buffer memory
    直接内存溢出,一般发生在NIO中(NIO程序经常通过ByteBuffer来读取或写入数据)
public static void main(String[] args) {
        System.out.println("配置的maxDirectMemory:" +
                (sun.misc.VM.maxDirectMemory() / (double) 1024 / 1024 + "MB"));
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);

    }
  1. OOM之unable to create new native thread
    产生原因:
  • 你的应用创建了太多的线程,一个应用进程创建多个线程,超过系统承载极限
  • 你的服务器并不允许你的应用程序创建这么多线程,linux系统默认允许单个进程可以创建的线程数是1024个。你的应用创建超过这个数据,就会报java.lang.OutOfMemoryError:unable to create new native thread.
    解决办法:
  • 想办法降低你应用程序创建线程的数量,分析应用是否真的需要创建这么多线程,如果不是,改代码将线程数降到最低。
  • 对于有的应用,确实需要创建很多线程,远超过linux系统默认的1024个线程的限制,可以通过修改linux服务器配置,扩大linux默认限制
public static void main(String[] args) {
        for (int i = 0; ; i++) {
            System.out.println("*********************i=" + i);
            new Thread(() -> {
                try {
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "" + i).start();
        }
    }
  1. OOM之Metaspace
    元空间溢出
    JDK1.8以后,Metaspace是方法区在Hotspot中的实现,它与持久代最大的区别在于:Metaspace并不在虚拟机内存中而是使用本地内存

相关文章

网友评论

      本文标题:对于OOM的理解

      本文链接:https://www.haomeiwen.com/subject/gwzzsktx.html