Files
StudyDiary-20261009/02-学习笔记/Tips/Linux 排查Java进程内存过高完整方法.md
CrazyJasonwell e97be9ac8c commit all
2026-10-09 22:06:40 +08:00

3.7 KiB
Executable File
Raw Blame History

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>

可以看到:堆内存、栈、共享库占用。

四、快速排查思路总结

  1. top / ps aux → 确认是 Java 进程占用高,拿到 PID

  2. jstat -gc PID 1000 → 观察 GC 行为,判断是内存泄漏还是堆配置太小

  3. jmap -heap PID → 看 JVM 堆参数是否合理(Xmx/Xms)

  4. jmap -dump 导出堆快照,MAT 分析定位泄漏对象

  5. jstack 辅助排查线程问题

五、常见原因

  1. 内存泄漏:代码创建对象没有释放(集合持续 add 不清理)

  2. JVM 参数不合理:-Xmx 设置太大,吃掉大量宿主机内存

  3. 堆外内存(DirectBuffer)占用:jmap 看不到堆外内存,需要额外排查

  4. 并发请求过高,正常业务内存开销

六、小提示

  • 如果是容器环境(docker),top看到的是容器内视图,宿主机需要额外查看

  • dump 堆文件会占用磁盘空间,hprof 文件体积可能很大

  • 如果 JDK 是精简版(没有自带 jmap/jstat),需要安装完整 JDK 或者使用arthas(阿里开源 Java 诊断工具)

如果你需要,我可以给你一份 Arthas 一键排查命令集,不需要依赖 JDK 自带工具。

(注:部分内容由豆包工作 AI 生成)