作者 l 会点代码的大叔(CodeDaShu)

JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看。

01

内存泄漏 & 内存溢出

1. 内存泄漏(memory leak )

申请了内存用完了不释放,比如一共有 1024M 的内存,分配了 521M 的内存一直不回收,那么可以用的内存只有 521M 了,仿佛泄露掉了一部分;

通俗一点讲的话,内存泄漏就是【占着茅坑不拉shi】。

2. 内存溢出(out of memory)

申请内存时,没有足够的内存可以使用;

通俗一点儿讲,一个厕所就三个坑,有两个站着茅坑不走的(内存泄漏),剩下最后一个坑,厕所表示接待压力很大,这时候一下子来了两个人,坑位(内存)就不够了,内存泄漏变成内存溢出了。

可见,内存泄漏和内存溢出的关系:内存泄露的增多,最终会导致内存溢出。

这是一个很有味道的例子。

如上图:

对象 X 引用对象 Y,X 的生命周期比 Y 的生命周期长;

那么当Y生命周期结束的时候,X依然引用着Y,这时候,垃圾回收期是不会回收对象Y的;

如果对象X还引用着生命周期比较短的A、B、C,对象A又引用着对象 a、b、c,这样就可能造成大量无用的对象不能被回收,进而占据了内存资源,造成内存泄漏,直到内存溢出。

02

泄漏的分类

  • 经常发生:发生内存泄露的代码会被多次执行,每次执行,泄露一块内存;

  • 偶然发生:在某些特定情况下才会发生;

  • 一次性:发生内存泄露的方法只会执行一次;

  • 隐式泄露:一直占着内存不释放,直到执行结束;严格的说这个不算内存泄露,因为最终释放掉了,但是如果执行时间特别长,也可能会导致内存耗尽。

03

导致内存泄漏的常见原因

1. 循环过多或死循环,产生大量对象;

2. 静态集合类引起内存泄漏,因为静态集合的生命周期和 JVM 一致,所以静态集合引用的对象不能被释放;下面这个例子中,list 是静态的,只要 JVM 不停,那么 obj 也一直不会释放。

public class OOM {static List list = new ArrayList();public void oomTests(){Object obj = new Object();list.add(obj);}
}

3. 单例模式,和静态集合导致内存泄露的原因类似,因为单例的静态特性,它的生命周期和 JVM 的生命周期一样长,所以如果单例对象如果持有外部对象的引用,那么这个外部对象也不会被回收,那么就会造成内存泄漏。

4. 数据连接、IO、Socket连接等等,它们必须显示释放(用代码 close 掉),否则不会被 GC 回收。

try {Connection conn = null;Class.forName("com.mysql.jdbc.Driver");conn = DriverManager.getConnection("url","", "");Statement stmt = conn.createStatement() ;ResultSet rs = stmt.executeQuery("....") ;
} catch (Exception e) {//异常日志
} finally {//1.关闭结果集 Statement//2.关闭声明的对象 ResultSet//3.关闭连接 Connection
}

5. 内部类的对象被长期持有,那么内部类对象所属的外部类对象也不会被回收。

6. Hash 值发生改变,比如下面中的这个类,它的 hashCode 会随着变量 x 的变化而变化:

public class ChangeHashCode {private int x ;@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;ChangeHashCode other = (ChangeHashCode) obj;if (x != other.x)return false;return true;}//省略 set 、get 方法
}
public class HashSetTests {public static void main(String[] args){HashSet<ChangeHashCode> hs = new HashSet<ChangeHashCode>();ChangeHashCode cc = new ChangeHashCode();cc.setX(10);//hashCode = 41hs.add(cc);cc.setX(20);//hashCode = 51System.out.println("hs.remove = " + hs.remove(cc));//falsehs.add(cc);System.out.println("hs.size = " + hs.size());//size = 2}
}

可以看到,在测试方法中,当元素的 hashCode 发生改变之后,就再也找不到改变之前的那个元素了;

这也是 String 为什么被设置成了不可变类型,我们可以放心地把 String 存入 HashSet,或者把 String 当做 HashMap 的 key 值;

当我们想把自己定义的类保存到散列表的时候,需要保证对象的 hashCode 不可变。

7. 内存中加载数据量过大;之前项目在一次上线的时候,应用启动奇慢直到夯死,就是因为代码中会加载一个表中的数据到缓存(内存)中,测试环境只有几百条数据,但是生产环境有几百万的数据。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

​Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子​相关推荐

  1. connection timed out是什么意思_Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子...

    作者 l 会点代码的大叔(CodeDaShu) JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 01 内存泄漏 & 内存溢出 1. 内存泄漏(memory lea ...

  2. 内存泄露和溢出的区别_Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子?...

    JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 内存泄漏 & 内存溢出 1. 内存泄漏(memory leak ) 申请了内存用完了不释放,比如一共有 1024M ...

  3. Java 中(堆溢出、内存溢出、栈溢出)

    Java 内存溢出有以下三种 (1) java.lang.OutOfMemoryError: Java heap space --JVM Heap(堆)溢出 JVM 在启动的时候会自动设置 JVM H ...

  4. 一位面试官询问我:Java中的JVM内存溢出和内存泄露是什么?我这么回答成功拿到了offer

    一位面试官询问我:Java中的JVM内存溢出和内存泄露是什么?我这么回答成功拿到了offer. 墨眉无锋墨家代码 2020-11-22 20:16:50 10525 收藏 56 分类专栏: Java ...

  5. Java内存溢出和内存泄露后怎么解决

    1.首先这里先说一下内存溢出和内存泄露的区别: 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但 ...

  6. java 内存溢出 内存泄露_java 内存泄露、内存溢出、内存不足

    内存泄露 什么是内存泄露? 在维基百科上的定义如图: 中文意思就是一个对象在内存中,而程序无法获取此对象,于是不能释放该对象所占用的内存. 百度百科上的定义如图: OWASP上的定义: 开发者无法释放 ...

  7. java 内存溢出和内存泄漏_JAVA中的内存溢出和内存泄漏有很大的区别

    JAVA中的内存溢出和内存泄漏分别是什么,有什么联系和区别,我谈谈自己的理解. 内存泄漏(memory leak ):申请了内存不释放,比如100m的内存,分配了10m的内存一直不回收,那么可以用的内 ...

  8. java内存泄漏跟栈溢出,8.《深入理解Java虚拟机》内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别...

    内存溢出和内存泄露的区别 内存溢出:指的是程序在申请内存的时候,没有足够大的空间可以分配了. 内存泄露:指的是程序在申请内存之后,没有办法释放掉已经申请到内存,它始终占用着内存,即被分配的对象可达但无 ...

  9. java什么时候可能产生内存溢出_JAVA内存泄露和内存溢出

    1)概念: 内存溢出:指在指定大小的内存空间,写入了超出大小的数据,从而导致了内存溢出. 内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误. 内存溢出通常发生于OLD段或Perm段垃圾回 ...

最新文章

  1. 【知识小课堂】4 之 索引
  2. HTTP/3 未来可期?
  3. ssl问题解决的过程
  4. (05)Verilog HDL时序逻辑:always
  5. exchange系列(一)exchange2010邮件服务器的安装与规划
  6. HCIE-Security Day18:防火墙用户管理(一)上网用户+本地认证(portal认证)
  7. Quartz.net 的 FAQ
  8. (7)Spring框架----面向切面编程(一个简单的约定游戏)
  9. 离散数学1 命题逻辑-基本的概念
  10. Skyline软件系列平台
  11. 一个在线文本比较工具
  12. ret2text涉及到的堆栈平衡问题
  13. Python+OpenCV3.3图像处理视频教程-贾志刚-专题视频课程
  14. 科研网站大全,你值得拥有!
  15. Windows设置调节音量的快捷键
  16. php获取汉字的首字母,php获取汉字拼音首字母的函数(真正可以使用的)
  17. px4初探-qgroundcontrol安装
  18. 计算机组成原理基础知识点
  19. Unity Shader 实现PS图层混合效果
  20. 炸裂了!3分钟用GPT4做一个PPT!

热门文章

  1. 组合计数 ---- Codeforces Round #370 (Div. 2)D. Memory and Scores[dp]
  2. php 上传乱码_如何解决php文件上传中文乱码问题
  3. mysql getconnection 如何关闭连接_【MySQL】使用连接池获取Connection执行sql以及mybatis事务注意事项...
  4. 使最新版Code::Blocks支持C++11标准
  5. java mvc数据库 封装_Springmvc对就jdbc封装的操作
  6. 鸿蒙推送升级包,华为鸿蒙系统已陆续推送!安卓可无缝升级,升级包容量高达6GB...
  7. 大一计算机考试题库window,2016年计算机考试Windows题库及答案
  8. 华为接入鸿蒙,华为将发布鸿蒙平板,魅族宣布接入鸿蒙系统
  9. python-web自动化-Python+Selenium之expected_conditions:各种判断
  10. Day43 前端基础--html