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

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

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

因此,从上面也可以推断出内存泄露可能会导致内存溢出。

二者的关系:🥂
内存溢出会抛出异常,内存泄露不会抛出异常,大多数时候程序看起来是正常运行的。

# 内存溢出或泄露原因分析

分析堆内存溢出的原因可能如下:🌴

  1. 使用了大量的递归或无限递归(递归中用到了大量的新建的对象)
  2. 使用了大量循环或死循环(循环中用到了大量的新建的对象)
  3. 类中和引用变量过多使用了 Static 修饰 如 public staitc Student s;在类中的属性中使用 static 修饰的最好只用基本类型或字符串。如 public static int i = 0; //public static String str;
  4. 数组,List,Map 中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放,会大量存储在内存中。

分析栈内存溢出的原因可能如下:🌴

  1. 使用了大量的递归或无限递归
  2. 使用了大量循环或死循环(如循环中不停调用方法)
  3. list,map,数组等长度过大等。

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

  1. 修改 JVM 启动参数 (-Xms,-Xmx),直接增加虚拟机内存。
  2. 检查错误日志。
  3. 使用内存查看工具查看内存使用情况 (如 jconsole)
  4. 对代码进行仔细分析,找出可能发生内存溢出的位置。

详细排查方案如下:🎈

  • 检查在数据库中取的数据量是否超过内存
  • 检查是否有过大的集合或对象
  • 检查是死循环或递归是否会导致溢出
  • 检查是否有大量对象的创建是否会出现内存问题
  • 检查是否有大量的连接对象或监听器等未关闭
    ......

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

  1. 尽量少使用枚举
  2. 尽量使用静态内部类而不是内部类
  3. 尽量使用轻量级的数据结构
  4. 养成关闭连接和注销监听器的习惯
  5. 谨慎使用 static 关键字
  6. 谨慎使用单例模式

🚀🚀🚀

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

田埂、 微信支付

微信支付

田埂、 支付宝

支付宝

田埂、 贝宝

贝宝