Files
StudyDiary-20261009/02-学习笔记/Tips/Linux 排查Java进程内存过高完整方法.md

159 lines
3.7 KiB
Markdown
Raw Normal View History

2026-10-09 22:06:40 +08:00
# Linux 排查Java进程内存过高完整方法
# Linux 排查 Java 进程内存过高完整方法
## 一、先找到占用高内存的 Java 进程
### 方式 1:top(最常用,实时查看)
```bash
top
```
- 按 `M` 大写 M:**按内存占用降序排序**
- 找到 `COMMAND` 列是 `java` 的行,记下 PID(第一列数字)
### 方式 2:htop(更友好,需要安装)
```bash
htop
```
### 方式 3:ps 一次性列出所有 java 进程,看 RSS \(物理内存\)
```bash
ps -ef | grep java
# 带内存占用版本
ps aux | grep java
```
> 字段说明:`%MEM` 内存占比,`RSS` 实际物理内存(单位 KB)
>
>
### 方式 4:只看 java 进程,排序内存
```bash
ps aux | grep -E 'java' | grep -v grep | sort -k4 -nr
```
---
## 二、拿到 PID 后,查看 JVM 内部内存情况(JDK 自带工具)
> ⚠️ 前提:运行 java 的用户和执行 jps/jstat/jmap 的用户一致,否则会权限失败
>
>
### 1\. jps 快速列出所有 Java 进程 \+ PID
```bash
jps -l
```
`-l`:打印完整主类名,方便区分是哪个 Java 应用
### 2\. jstat 持续监控 JVM 堆内存变化(判断是否内存泄漏)
```bash
# 每1秒输出一次,持续观察,PID替换成你的java进程号
jstat -gc <PID> 1000
```
重点看这几列:
- `S0C,S1C`:Survivor 区容量
- `EC,OC`:Eden、Old 老年代容量
- `OU`:Old 区已使用大小
> 如果 **OU 持续上涨,Full GC 频繁但内存释放很少 → 大概率内存泄漏**
>
>
### 3\. jmap 查看堆内存快照(dump 内存文件,事后分析)
```bash
# 生成堆dump文件(会短暂STW,生产环境谨慎操作)
jmap -dump:format=b,file=heapdump.hprof <PID>
```
得到 `heapdump.hprof` 文件,可以下载到本地,用 **MAT\(Memory Analyzer Tool\)** 分析,定位是哪个对象占用大量内存。
查看堆内存概况(不用生成文件):
```bash
jmap -heap <PID>
```
输出 JVM 堆配置:新生代、老年代大小,GC 收集器类型。
查看对象统计:
```bash
jmap -histo <PID>
```
列出所有类实例数量、占用内存,找出占用最多的类。
### 4\. jstack 查看线程栈(排查是否线程堆积间接导致内存暴涨)
```bash
jstack <PID>
```
用来查找死锁、大量等待线程。
---
## 三、查看进程级详细内存(Linux 系统层面,区分 JVM 堆 / 非堆)
```bash
# 查看进程smaps,详细内存分布
cat /proc/<PID>/smaps
```
或者用 `pmap`
```bash
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 生成)