Java 内存泄漏(Memory Leak)通常指:对象已经不再被使用,但由于某些引用未被释放,导致 GC 无法回收,最终引发 OOM(OutOfMemoryError)。下面从 排查思路 → 工具 → 实战步骤 → 常见原因 系统说明。
不是所有内存上涨都是泄漏:
✅ 判断标准:
java.lang.OutOfMemoryError: Java heap space找“谁持有了本该释放的对象”
内存泄漏本质:
本该被回收的对象 → 被静态变量 / 线程 / 集合 / 监听器 持有
jstatjstat -gcutil <pid> 1000
看:
O(老年代)是否持续上涨
FGC 是否频繁但内存不降
jmap(看对象分布)
jmap -histo:live <pid> | head -20
jmap -dump:live,format=b,file=heap.hprof <pid>
或 JVM 参数(OOM 自动 dump):
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heap.hprof
| 工具 | 说明 |
|---|---|
| MAT (Eclipse Memory Analyzer) | 最强,推荐 |
| VisualVM | 简单直观 |
| JProfiler | 商业、好用 |
| Arthas | 线上实时分析 |
选择:
MAT 会自动告诉你:
“XX 对象占用了 80% 内存,被谁引用”
常见路径:
Static Map
→ Thread
→ ThreadLocal
→ Listener
重点看:
static 变量ThreadLocaldashboard
heapdump /tmp/heap.hprof
thread
看是否有:
public static List<Object> cache = new ArrayList<>();
✅ 解决:
WeakHashMapthreadLocal.set(obj);
// 没 remove
✅ 解决:
try {
threadLocal.set(x);
} finally {
threadLocal.remove();
}
addListener 没 removeListenerExecutors.newFixedThreadPool(1000);
✅ 用:
new ThreadPoolExecutor(...)
✅ 用:
✅ 编码规范:
static List/Map✅ JVM 参数:
-Xmx512m
-XX:+HeapDumpOnOutOfMemoryError
Java 内存泄漏 = 对象活着但没人用,GC 不敢杀
如果你愿意,可以:
我可以帮你 精准定位是哪一行代码的问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。