内存泄漏与内存溢出

Posted mingyi123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄漏与内存溢出相关的知识,希望对你有一定的参考价值。

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

## memory leak会最终会导致out of memory!


内存泄漏

长生命周期的对象引用短声明周期的对象,导致短生命周期的对象在生命周期已结束后还无法回收对象内存 ,造成内存泄漏

场景

  • 1、静态集合引用对象
public class dome1 {
    static Set<Object> s = new HashSet(10);
    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {
            Object o = new Object();
            s.add(o);
            //对象赋值位空值,理应被垃圾回收器回收,但是被集合引用,
            // 但是GC-Roots 到对象之间存在引用链(可到达),
            //所以不会被回收内存
            o = null;
        }
        s.forEach(System.out::println);
    }
}
  • 2、集合里面的对象属性被修改,在调用remove()方法时不起作用,造成对象删除不掉,造成内存泄漏
HashSet<Person> set = new HashSet<>();
Person tom = new Person(1L, "Tom", 12);
System.out.println(tom.hashCode());//2613467
set.add(tom);
tom.setAge(13);//修改对象的属性后对象的hashCode发生变化
System.out.println(tom.hashCode());//2613468
System.out.println(set.remove(tom));//false  remove不成功,造成内存泄漏
set.forEach(System.out::println);
System.out.println(set.add(tom));// true  添加成功,判断是否相等时验证hashCode
set.forEach(System.out::println);
  • 3、监听器未删除

  • 4、各种连接为关闭

数据库链接、网络链接、IO链接必须显式的调用close关闭链接,否则不会被GC回收

  • 5、内部类和外部模块的引用

  • 6、单例模式引用其他对象
    单例模式为静态资源,整个JVM生命周期都有效,如果单例对象持有对外部对象的引用,那么这个外部对象不会被GC回收,导致内存泄漏
if (true){
    Person tom = new Person(1L, "Tom", 12);
    singleton.getInstance().setPerson(tom);
}
System.out.println(singleton.getInstance().getPerson());

对象tom已经结束生命周期,但是被单例对象引用,不会被GC回收

二、内存溢出

在Java堆中不断的创建对象造成

大量的内存泄漏


以上是关于内存泄漏与内存溢出的主要内容,如果未能解决你的问题,请参考以下文章

Android中的内存泄漏和内存溢出

内存泄漏与溢出

内存溢出与内存泄漏区别

内存溢出与内存泄漏

内存泄漏与内存溢出是什么?

内存溢出与内存泄漏