温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java内存泄漏怎么排查

发布时间:2026-10-08 19:09:42 来源:亿速云 阅读:103 作者:小樊 栏目:编程语言

Java 内存泄漏(Memory Leak)通常指:对象已经不再被使用,但由于某些引用未被释放,导致 GC 无法回收,最终引发 OOM(OutOfMemoryError)。下面从 排查思路 → 工具 → 实战步骤 → 常见原因 系统说明。


一、先确认是不是“真泄漏”

不是所有内存上涨都是泄漏:

  • 缓存设计不合理(持续增长)
  • 流量高峰期正常占用
  • 大对象临时使用

✅ 判断标准:

  • 堆内存持续上涨,Full GC 后不下降
  • 老年代使用率只增不减
  • 最终抛出 java.lang.OutOfMemoryError: Java heap space

二、排查核心思路(非常重要)

找“谁持有了本该释放的对象”

内存泄漏本质:

本该被回收的对象 → 被静态变量 / 线程 / 集合 / 监听器 持有

三、常用排查工具(从简单到专业)

1️⃣ 基础监控(先快速看)

  • jstat
jstat -gcutil <pid> 1000

看:

  • O(老年代)是否持续上涨

  • FGC 是否频繁但内存不降

  • jmap(看对象分布)

jmap -histo:live <pid> | head -20

2️⃣ 堆转储(最关键)

jmap -dump:live,format=b,file=heap.hprof <pid>

或 JVM 参数(OOM 自动 dump):

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heap.hprof

3️⃣ 分析工具(必用)

工具 说明
MAT (Eclipse Memory Analyzer) 最强,推荐
VisualVM 简单直观
JProfiler 商业、好用
Arthas 线上实时分析

四、MAT 实战排查步骤(重点)

Step 1:打开 heap.hprof

选择:

  • Leak Suspects Report

MAT 会自动告诉你:

“XX 对象占用了 80% 内存,被谁引用”


Step 2:看 Dominator Tree

  • 找出 Retained Heap 最大 的对象
  • 看引用链(Path to GC Roots)

常见路径:

Static Map
→ Thread
→ ThreadLocal
→ Listener

Step 3:分析 GC Roots

重点看:

  • static 变量
  • 存活线程
  • ThreadLocal
  • 单例对象

五、Arthas 线上快速定位(推荐)

dashboard
heapdump /tmp/heap.hprof
thread

看是否有:

  • 线程数暴涨
  • 某个线程持有大量对象

六、Java 内存泄漏常见原因(高频)

1️⃣ static 集合未清理

public static List<Object> cache = new ArrayList<>();

✅ 解决:

  • 用 WeakHashMap
  • 加过期机制(LRU)

2️⃣ ThreadLocal 使用不当

threadLocal.set(obj);
// 没 remove

✅ 解决:

try {
  threadLocal.set(x);
} finally {
  threadLocal.remove();
}

3️⃣ 监听器 / 回调未注销

  • addListener 没 removeListener
  • Spring Bean 销毁未清理

4️⃣ 线程池滥用

Executors.newFixedThreadPool(1000);

✅ 用:

new ThreadPoolExecutor(...)

5️⃣ 缓存无限增长

  • 没有 TTL
  • 没有大小限制

✅ 用:

  • Caffeine
  • Guava Cache

七、预防比排查更重要

✅ 编码规范:

  • 不用 static List/Map
  • ThreadLocal 必须 remove
  • 缓存必须限大小 + 过期
  • 及时关闭资源(IO / Connection)

✅ JVM 参数:

-Xmx512m
-XX:+HeapDumpOnOutOfMemoryError

八、总结一句话

Java 内存泄漏 = 对象活着但没人用,GC 不敢杀

如果你愿意,可以:

  • 发 报错堆栈
  • 或说 使用的框架(Spring / Netty / Tomcat)
  • 或贴 jstat / MAT 截图

我可以帮你 精准定位是哪一行代码的问题。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手