内存泄漏和溢出

文章目录


前言

内存泄漏(Memory Leak)和内存溢出(Memory Overflow,通常称为 OOM)是软件开发中两个紧密相关但本质完全不同的概念。简单来说,内存泄漏是"该还的没还",而内存溢出是"借不到钱了"。

维度 内存泄漏 (Memory Leak) 内存溢出 (Out Of Memory - OOM)
本质 资源回收失败:无用对象因未被释放而一直占用内存。 资源分配失败:申请的内存超过了系统可用的上限。
表现 内存使用量缓慢、持续地增长(像慢性病)。 程序突然崩溃,抛出 OutOfMemoryError 异常。
因果关系 是导致内存溢出的常见诱因(长期泄漏最终耗尽内存)。 是内存泄漏的最终结果之一,但也可能由其他原因直接引起。
类比 租了房子不退,钥匙也不还,导致空房越来越少。 想租房子时,发现所有房子都被占用了,没房可租了。

一、内存泄漏

内存泄漏指的是程序在运行过程中,由于疏忽或错误,未能释放那些已经不再使用的内存。这些内存块虽然对程序已经无用,但因为某些原因(如被错误的引用持有)无法被垃圾回收器(GC)回收。

  • 常见原因:
    • 长生命周期对象持有短生命周期对象:例如,静态集合类(static List)一直往里添加对象,导致对象无法被回收。
    • 未关闭的资源:数据库连接(Connection)、文件流(InputStream)、网络连接等使用后未调用 close() 方法。
    • 内部类持有外部类引用:非静态内部类(如 Android 中的 Handler)隐式持有外部类(Activity)的引用,导致外部类无法销毁。
    • 监听器/回调未注销:注册了监听器但忘记注销,导致对象一直被引用。
  • 后果:程序运行越来越慢,内存占用越来越高,最终可能导致系统卡顿或触发 OOM。

二、内存溢出

内存溢出指的是程序在申请内存时,系统没有足够的内存空间供其使用。这通常发生在程序需要的内存超过了 JVM 配置的最大限制(如 -Xmx 参数),或者操作系统本身无法提供更多内存时。

  • 常见原因:
    • 内存泄漏的累积:这是最常见的原因,长期的泄漏最终耗尽了堆内存。
    • 加载数据量过大:例如一次性从数据库查询几百万条数据到内存中,或者读取一个超大文件到字节数组。
    • 配置过小:JVM 堆内存参数(-Xmx)设置得太小,不足以支撑业务运行。
    • 死循环或无限递归:导致栈空间不断被消耗(栈溢出 StackOverflowError)。
  • 后果:程序直接崩溃,抛出 java.lang.OutOfMemoryError 错误,服务中断。

如何排查与解决?

  • 排查内存泄漏:
    • 工具:使用内存分析工具,如 Java 的 MAT (Memory Analyzer Tool)、VisualVM、JProfiler。
    • 方法:监控内存使用曲线,如果内存随时间推移呈"锯齿状"上升且 GC 后不回落,极有可能是内存泄漏。通过工具分析堆转储文件(Heap Dump),找到"支配树"(Dominator Tree)中占用内存最大的对象及其引用链。
  • 解决内存泄漏:
    • 及时将不用的对象设为 null(虽然通常不需要,但在极端场景下有用)。
    • 使用 try-with-resources 语法自动关闭资源。
    • 避免使用静态集合类无限制地存储对象,或使用弱引用(WeakReference)。
    • 及时注销监听器和回调。
  • 解决内存溢出:
    • 应急:适当增加 JVM 内存参数(如 -Xmx4g),但这只是缓兵之计。
    • 优化代码:检查是否有一次性加载大数据的逻辑,改为分页或流式处理。
    • 修复根本问题:如果是由于内存泄漏导致的溢出,必须先修复泄漏点。
相关推荐
码智社35 分钟前
Java实现RSA密钥生成、加密解密、加签验签
java
wear工程师43 分钟前
ThreadLocal 在线程池里为什么会串数据:别只会答内存泄漏
java·后端
Iruoyaoxh44 分钟前
栈和队列~
java·开发语言
审小匠OpenCPAi1 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
码上上班1 小时前
docker课程
java·docker·容器
腻害兔1 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
达子6662 小时前
第9章_HarmonyOs图解 用Java开发UI
java·ui·harmonyos
龙虾PRO3 小时前
能源与股票量化核心差异,AI全链路落地实操手册
java·面试·职场和发展
llwszx4 小时前
【Java/Go后端手撸原生Agent(第九篇):Plan-and-Execute规划模式——从“走一步看一步“到“先谋后动“】
java·python·golang·agent开发·plan模式·规划执行模式
ZJH__GO4 小时前
网络编程v2--多客户端互通
java·运维·服务器·开发语言·计算机网络