0%

内存溢出和内存泄漏

内存溢出和内存泄漏

内存溢出

内存溢出(OutOfMemoryError,简称OOM)是指没有空闲内存,且垃圾收集器也无法提供更多的内存

出现OOM的原因有两种:

  • java虚拟机设置的堆内存不够
  • 代码中创建了大量大对象,并且长时间不能被垃圾收集器收集

内存泄漏

可达性分析算法来判断对象是否是不再使用的对象,本质是判断一个对象是否还被引用,内存泄漏是指对象不会被程序用到了,但是GC又无法回收这些对象的情况,内存泄漏会逐渐的占用内存,直至耗尽所有内存,最终出现OOM

内存泄露的八种情况

  • 静态集合类

    1
    2
    3
    4
    5
    6
    7
    static List<Object> list = new ArrayList<>();

    public void test(){
    // 由于list是静态的,与JVM的生命周期相同,所以obj对象不会被回收
    Object obj = new Object();
    list.add(obj);
    }
  • 单例模式

    单例模式的对象实例是静态的,生命周期和JVM的生命周期相同,如果单例对象持有外部对象的引用,也会导致外部对象不会被回收

  • 内部类持有外部类

    内部类持有外部类对象,如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象也不会被垃圾回收

  • 各种连接(数据库连接、网络连接、io连接)

  • 变量不合理的作用域

  • 改变哈希值

  • 缓存泄漏

    可以使用WeakHashMap来使用缓存,当除了自身对key的引用外,此key没有其他引用,那么此map会自动丢弃此值

  • 监听器和回调