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

内存泄漏(Memory Leak)内存溢出(Out Of Memory,OOM) 是两个经常一起出现但本质不同的问题

一、内存泄漏是什么

定义

程序中有一些对象:

  • 已经不再使用
  • 但是仍然被引用着
  • 导致 GC(垃圾回收)无法回收

类比生活中抽象的说法:占着茅坑不拉屎,导致后面的人没地方

这些无法释放的内存会不断积累。

这就叫: 该释放的内存没有释放

特征

随着程序运行时间增长:

  • JVM 内存占用越来越高
  • Full GC 越来越频繁
  • 系统越来越卡
  • 最终可能导致 OOM

Java 示例

java 复制代码
public class MemoryLeakDemo {

    private static List<Object> list = new ArrayList<>();

    public static void main(String[] args) {

        while (true) {
            list.add(new byte[1024 * 1024]); // 1MB
        }
    }
}

这里的问题:

  • list 是静态集合
  • 对象一直被 list 引用
  • GC 永远无法回收

结果:

  • 内存不断增长,导致可用内存逐渐变小
  • 最终 OOM

这属于:内存泄漏导致的内存溢出

二、内存溢出(OOM)是什么

定义

程序申请内存时:

  • JVM 已经没有足够内存
  • 且 GC 后仍无法获得足够空间

于是 JVM 抛出:

java 复制代码
java.lang.OutOfMemoryError

这个就是:内存溢出

本质

OOM 的本质是: 内存不够用了

三、两者核心区别

对比项 内存泄漏 内存溢出
本质 无用对象无法被回收,导致可用内存越来越小 内存不足
是否一定报错 不一定 一定会报错
是否会导致 OOM 可能会 本身就是 OOM
问题性质 资源管理问题 内存容量问题
发生速度 通常逐渐恶化 可以瞬间发生
常见原因 引用未释放 内存申请过大

四、它们之间的关系

内存泄漏 ------> 导致可用内存越来越小 ------> 内存不够用 ------> 触发OOM

也就是说 :内存泄漏通常是 OOM 的原因之一

但是 :OOM 不一定是全是由内存泄漏导致的

五、OOM 不一定是泄漏

例如:

java 复制代码
byte[] bytes = new byte[1024 * 1024 * 1024];

直接申请 1GB的内存:

  • 如果 JVM 堆只有 512MB
  • 会立刻 OOM

这里:没有发生 内存泄漏 只是 申请过大

六、Java 中常见的内存泄漏场景

1. 静态集合持有对象

java 复制代码
static List<User> cache = new ArrayList<>();

生命周期和 JVM 一样

2. ThreadLocal 未 remove

java 复制代码
threadLocal.set(value);

线程池线程不会销毁

如果不:

java 复制代码
threadLocal.remove();

可能泄漏。

3. 监听器/回调未注销

例如:

  • EventListener
  • Observer
  • Netty Handler

对象一直被引用着

4. 数据库连接未关闭

复制代码
Connection conn

导致连接池资源耗尽

5. 缓存无限增长

例如:创建一个大对象 只放不删,一直没有被回收

复制代码
Map<String, Object> cache = new HashMap<>();

七、总结

内存泄漏

不该活着的(不在使用的)对象还活着,导致可用内存逐渐变小

内存溢出

JVM 已经没内存可用了,新的对象申请不到内存了

相关推荐
曦夜日长1 小时前
C++ STL容器string(二):删除与插入、数据查找、自定义输入
java·开发语言·c++
jimy11 小时前
C语言中的inline function specifier(函数说明符、关键字)
c语言·开发语言
赏金术士1 小时前
Kotlin 协程底层原理(Continuation)详解
java·开发语言·kotlin
手揽回忆怎么睡1 小时前
springboot3使用ProGuard混淆jar
java·jar
dadaobusi2 小时前
PCIe的ATS和PRS
java·网络·数据库
南境十里·墨染春水2 小时前
线程池学习(二)线程池理解
java·jvm·学习
ZGi.ai2 小时前
私有化大模型接入企业系统:SSO+权限+API网关完整方案
java·开发语言·大模型·私有化部署·sso·企业架构
Han_han9192 小时前
集合进阶(Map集合):
java
吴声子夜歌2 小时前
Java——文件和目录操作
java·文件·目录