美文网首页
内存溢出

内存溢出

作者: 紫色红色黑色 | 来源:发表于2019-12-24 23:55 被阅读0次

    OutOfMemoryError

    java.lang.OutOfMemoryError: Java heap space

    原因:
    1.在l号的heap中分配xxl号的内存;
    2.内存泄露

    下面代码演示堆内存溢出
    -XX:+PrintGCDetails -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

    public static void main(String[] args) {
        byte[] bytes = new byte[1 * 1024 * 1024];
    
        List<Object> list = new ArrayList<>();
    
        while (true) {
            list.add(bytes);
        }
    }
    

    Memory Leak

    内存泄露的表现是内存溢出。下面是测试代码,向map中put元素,而元素没有重写equals()和hashCode(),所以map会判断key是新的,结果就是不停的向map中put元素。

    public class MemLeadDemo {
    
        public final String key;
    
        public MemLeadDemo(String key) {
            this.key = key;
        }
    
        public static void main(String[] args) {
            try {
                Map map = System.getProperties();
    
                for (; ; ) {
                    map.put(new MemLeadDemo("key"), "value");
                    Thread.sleep(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    
    

    jvm参数

    -XX:+PrintGCDetails -Xmx10m -Xms10m -XX:+HeapDumpOnOutOfMemoryError
    

    使用VisualVM(文档速度慢,需要等待)观察内存情况,需要安装插件Visual GC
    。可以看到full gc越来越多,并且老生代并没有减少内存。

    内存泄露

    在内存溢出后查看dump文件,可以看到实例数最多的是散列表中的entry。


    dump文件

    java.lang.OutOfMemoryError: Metaspace

    原因:加载类过多,超过Metaspace区域
    下面代码演示metaspace溢出
    -XX:+PrintGCDetails -XX:MaxMetaspaceSize=10m -XX:MetaspaceSize=10m -XX:+HeapDumpOnOutOfMemoryError

    public static void main(String[] args) {
        while (true) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(MetaOom.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                    return proxy.invokeSuper(obj, args);
                }
            });
    
    
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            enhancer.create();
        }
    }
    
    static class MetaOom {}
    

    栈内存溢出

    java.lang.StackOverflowError
    -Xss160K设置每个线程栈内存

    public static void main(String[] args) {
        StackOom oom = new StackOom();
        try {
            oom.recursive();
        } catch (Throwable throwable) {
            System.out.println(oom.count);
            throwable.printStackTrace();
        }
    }
    
    private int count = 0;
    public void recursive() {
        count++;
        recursive();
    }
    

    引用

    https://plumbr.io/outofmemoryerror
    https://www.jianshu.com/p/2fdee831ed03
    https://www.toptal.com/java/hunting-memory-leaks-in-java

    相关文章

      网友评论

          本文标题:内存溢出

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