内存溢出和内存泄露分析及解决方案

时间:2022-07-03 20:57:22

1.  内存溢出和内存泄露的区别与联系

  内存溢出 out of memory,指程序要求的内存超出了系统所能分配的范围,出现out of memory;比如申请一个int类型,但给了它一个int才能存放的数,就会出现内存溢出,或者是创建一个大的对象,而堆内存放不下这个对象,这也是内存溢出。

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

  因此,我们从上面也可以推断出内存泄露可能会导致内存溢出。内存溢出会抛出异常,内存泄露不会抛出异常,大多数时候程序看起来是正常运行的。

2. 内存溢出和内存泄露的案例

public class demo {//内存溢出案例
    public static void main(String[] args) {
        List<Object> list=new ArrayList<>();
        while(true){//申请的内存过大
            int[] temp=new int[1000];
            list.add(temp);
        }
    }
}

 

public class demo {//内存泄露案例
    public static void main(String[] args) {
        Vector<Object> v = new Vector<>(1000);
        for (int i = 1; i<1000; i++)
        {
            Object o = new Object();
            v.add(o);
            o = null;
        }
    }
}

 3.内存溢出和内存泄露的原因

  内存溢出的详解参考上一篇博客https://www.cnblogs.com/ywb-articles/p/10530813.html

    内存泄露的可能原因:

    1、长生命周期的对象持有短生命周期对象的引用,即静态集合类,如上面的Vector和HashMap等。

    2、大量无用对象的创建

    3、各种连接没显示关闭。如: 数据库连接、网络连接、IO连接,未关闭连接会造成很多对象无法回收。

    4、监听器。释放对象时没有删除监听器。

4.出现内存溢出或内存泄露的解决方案

  1.修改JVM启动参数(-Xms,-Xmx),直接增加虚拟机内存。

  2.检查错误日志。

  3.使用内存查看工具查看内存使用情况(如jconsole)

  4.对代码进行仔细分析,找出可能发生内存溢出的位置。

  详细排查方案如下:

    a.检查在数据库中取的数据量是否超过内存

    b.检查是否有过大的集合或对象

    c.检查是死循环或递归是否会导致溢出

    d.检查是否有大量对象的创建是否会出现内存问题

    e.检查是否有大量的连接对象或监听器等未关闭

    ......

5.在开发中应如何避免出现内存泄露

  1.尽量少使用枚举,枚举的详解参考博客:https://blog.csdn.net/xiao_nian/article/details/80002101

    2.尽量使用静态内部类而不是内部类

    3.尽量使用轻量级的数据结构

    4.养成关闭连接和注销监听器的习惯

    5.谨慎使用static关键字

    6.谨慎使用单例模式

    ......