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

内存泄漏(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 已经没内存可用了,新的对象申请不到内存了

相关推荐
weixin199701080161 分钟前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存
波加曼大王3 分钟前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
SL_staff7 分钟前
目标健康度自检清单:开发者视角下的目标-计划-任务链路断点诊断
java·开源·github
for_ever_love__11 分钟前
MySQL 高频面试题 30 问:索引、事务、锁、日志、主从与分库分表(MySQL 8.0 版)
java·数据库·spring boot·mysql·spring cloud·面试·总结
神仙别闹12 分钟前
基于C++实现的贪吃蛇游戏平台
java·c++·游戏
ACP广源盛1392462567315 分钟前
Type‑C 扩展坞方案选型笔记|国产 DP1.4 转 HDMI2.0 桥接芯片 GSV2201S @ACP评估
c语言·开发语言·笔记·硬件架构·硬件工程·国产芯片
布吉岛的石头21 分钟前
Java 程序员第 49 阶段11:Java 接 BERT:用 ONNX Runtime 做句向量推理
java·人工智能·python·深度学习·bert·transformer
niucloud-admin30 分钟前
JAVA V6 多商户商城 开发文档——JAVA服务端
java·开发语言
alexlifexyz44 分钟前
写了个 Claude Code 插件:AI 写的 Java 违反阿里规约,就写不进文件
java
轻舟技术A1 小时前
Pi 的 Rust 实现来了:rpi,不止一个终端 Agent
开发语言·后端·rust