3.7 KiB
Executable File
Linux 排查Java进程内存过高完整方法
Linux 排查 Java 进程内存过高完整方法
一、先找到占用高内存的 Java 进程
方式 1:top(最常用,实时查看)
top
-
按
M大写 M:按内存占用降序排序 -
找到
COMMAND列是java的行,记下 PID(第一列数字)
方式 2:htop(更友好,需要安装)
htop
方式 3:ps 一次性列出所有 java 进程,看 RSS (物理内存)
ps -ef | grep java
# 带内存占用版本
ps aux | grep java
字段说明:
%MEM内存占比,RSS实际物理内存(单位 KB)
方式 4:只看 java 进程,排序内存
ps aux | grep -E 'java' | grep -v grep | sort -k4 -nr
二、拿到 PID 后,查看 JVM 内部内存情况(JDK 自带工具)
⚠️ 前提:运行 java 的用户和执行 jps/jstat/jmap 的用户一致,否则会权限失败
1. jps 快速列出所有 Java 进程 + PID
jps -l
-l:打印完整主类名,方便区分是哪个 Java 应用
2. jstat 持续监控 JVM 堆内存变化(判断是否内存泄漏)
# 每1秒输出一次,持续观察,PID替换成你的java进程号
jstat -gc <PID> 1000
重点看这几列:
-
S0C,S1C:Survivor 区容量 -
EC,OC:Eden、Old 老年代容量 -
OU:Old 区已使用大小
如果 OU 持续上涨,Full GC 频繁但内存释放很少 → 大概率内存泄漏
3. jmap 查看堆内存快照(dump 内存文件,事后分析)
# 生成堆dump文件(会短暂STW,生产环境谨慎操作)
jmap -dump:format=b,file=heapdump.hprof <PID>
得到 heapdump.hprof 文件,可以下载到本地,用 MAT(Memory Analyzer Tool) 分析,定位是哪个对象占用大量内存。
查看堆内存概况(不用生成文件):
jmap -heap <PID>
输出 JVM 堆配置:新生代、老年代大小,GC 收集器类型。
查看对象统计:
jmap -histo <PID>
列出所有类实例数量、占用内存,找出占用最多的类。
4. jstack 查看线程栈(排查是否线程堆积间接导致内存暴涨)
jstack <PID>
用来查找死锁、大量等待线程。
三、查看进程级详细内存(Linux 系统层面,区分 JVM 堆 / 非堆)
# 查看进程smaps,详细内存分布
cat /proc/<PID>/smaps
或者用 pmap
pmap -x <PID>
可以看到:堆内存、栈、共享库占用。
四、快速排查思路总结
-
top/ps aux→ 确认是 Java 进程占用高,拿到 PID -
jstat -gc PID 1000→ 观察 GC 行为,判断是内存泄漏还是堆配置太小 -
jmap -heap PID→ 看 JVM 堆参数是否合理(Xmx/Xms) -
jmap -dump导出堆快照,MAT 分析定位泄漏对象 -
jstack辅助排查线程问题
五、常见原因
-
内存泄漏:代码创建对象没有释放(集合持续 add 不清理)
-
JVM 参数不合理:
-Xmx设置太大,吃掉大量宿主机内存 -
堆外内存(DirectBuffer)占用:jmap 看不到堆外内存,需要额外排查
-
并发请求过高,正常业务内存开销
六、小提示
-
如果是容器环境(docker),
top看到的是容器内视图,宿主机需要额外查看 -
dump 堆文件会占用磁盘空间,hprof 文件体积可能很大
-
如果 JDK 是精简版(没有自带 jmap/jstat),需要安装完整 JDK 或者使用
arthas(阿里开源 Java 诊断工具)
如果你需要,我可以给你一份 Arthas 一键排查命令集,不需要依赖 JDK 自带工具。
(注:部分内容由豆包工作 AI 生成)