服务器内存过高排查流程

服务器内存过高排查流程

一、整机内存:先判断是不是真有问题

1. 看整体

free -h

指标 怎么看
available 最重要,表示还能给程序用的内存
buff/cache 文件缓存,可回收,不等于"被占死"
Swap 若持续被大量使用,说明物理内存已经紧张

结论:

  • available 还充足 → 可能只是缓存高,不必立刻处理
  • available 很低 + Swap 持续涨 → 需要继续往下查

2. 看全部进程占用(整机排查的核心一步)

ps aux --sort=-%mem | head -20

或实时刷新:

top

按 M:按内存排序

按 P:按 CPU 排序

按 q:退出

记录前几名的:PID、进程名、%MEM、RSS。

列 含义
RSS 实际物理内存(KB),最可靠
%MEM 占整机内存百分比
VSZ 虚拟内存,Java 等进程常很大,参考价值低

换算:RSS(MB) = RSS(KB) ÷ 1024


3. 整机排查流程

free -h

↓ 是否 really 紧张?

ps aux --sort=-%mem | head -20

↓ 找出占用最高的几个进程

ps -fp <PID> 确认进程是什么

↓

按类型分析(Java / 数据库 / Web / 未知)

↓

判断:正常负载 / 配置过大 / 泄漏 / 重复进程 / 异常进程

↓

处理 + 持续观察

确认某个 PID 是什么:

ps -fp <PID>

cat /proc/<PID>/cmdline | tr '\0' ' '

4.根据端口号查看对应pid

root@01 \~# ss -tlnp | grep 12510

LISTEN 0 100 :::12510 :::* users:(("java",pid=21119,fd=603))

root@01 \~# ss -tlnp | grep 12590

LISTEN 0 100 :::12590 :::* users:(("java",pid=22280,fd=602))

5.kill进程

kill -9 <PID>


二、单个进程内存过高:通用流程

原则:先看全部,再聚焦一个。

第 1 步:看全部进程占用情况

ps aux --sort=-%mem | head -20

确认:

  • 该进程在排行榜第几名
  • 是否多个同类进程叠加占用
  • 是否还有其它进程占更大头

第 2 步:聚焦目标进程

ps -p <PID> -o pid,user,rss,vsz,%mem,%cpu,etime,cmd

字段 用途
rss 当前实际占用
etime 运行了多久
%cpu 是否伴随 CPU 异常

第 3 步:判断"正常高"还是"异常高"

现象 可能原因
一启动就很高,之后稳定 启动参数或默认配置预留了较多内存
业务高峰时升高,过后回落 正常负载波动
持续缓慢上涨,长期不回落 内存泄漏嫌疑
同类进程有多个 重复启动、未停旧进程
进程在但服务不可用 失败残留进程

第 4 步:按进程类型继续查

Java 进程

是否 OOM / GC 问题

grep -i "OutOfMemory\|GC overhead\|Metaspace" /path/to/app.log

有 JDK 时看 GC

jstat -gc <PID> 2000 10

jmap -heap <PID>

关注:堆、Metaspace、Full GC 后内存是否下降。

数据库(MySQL / PostgreSQL 等)

ps -fp <PID>

MySQL 示例

mysql -e "SHOW VARIABLES LIKE '%buffer%';"

mysql -e "SHOW PROCESSLIST;"

常见:缓冲池、连接数、大查询。

Redis

redis-cli info memory

关注:used_memory、是否达到 maxmemory。

Nginx / 其它

ps -fp <PID>

ls -l /proc/<PID>/exe

看 worker 数量、是否异常 fork。


第 5 步:看系统对该进程的限制与详情

进程详细内存分布(Linux)

cat /proc/<PID>/status | grep -E 'VmRSS|VmSize|Threads'

打开的文件、连接数(辅助判断泄漏)

ls /proc/<PID>/fd | wc -l

ss -tp | grep <PID>


第 6 步:处理思路(通用)

情况 处理
重复进程 只保留有效实例,停掉其余
配置过大 调小内存相关配置(JVM、DB buffer 等)
临时高峰 观察,必要时扩容或限流
疑似泄漏 重启缓解 + 抓 dump/日志 + 修代码
未知进程 确认来源,不应存在则停掉并排查入侵

第 7 步:处理后验证

free -h

ps aux --sort=-%mem | head -20

ps -p <PID> -o pid,rss,%mem,etime

持续观察一段时间,确认是否再次上涨。


三、一张总流程图

内存告警

↓

free -h(看 available / swap)

↓

ps aux --sort=-%mem | head -20(看全部进程)

↓

锁定 1~3 个可疑 PID

↓

ps -fp PID(确认是什么程序)

↓

分支排查

├─ Java → 日志 / jstat / GC / dump

├─ DB → 缓冲池 / 连接 / 慢 SQL

├─ Redis → info memory

└─ 其它 → 路径 / 配置 / 是否重复

↓

处理 → 再跑 free + ps 验证


四、常用命令速查

整机

free -h

全部进程按内存排序

ps aux --sort=-%mem | head -20

单个进程

ps -p <PID> -o pid,rss,vsz,%mem,%cpu,etime,cmd

实时

top

进程详情

ps -fp <PID>

cat /proc/<PID>/status | grep Vm


核心习惯:查单个进程之前,先用 ps aux --sort=-%mem 看全局排行,避免只盯一个进程、忽略真正的大头。

相关推荐
誰能久伴不乏1 小时前
桌面客户端的运行日志系统:SQLite 分块 + 独立写线程 + 文本降级
数据库·c++·qt·架构·sqlite
程序员清风9 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
正在走向自律10 小时前
数据集成产品的技术底座:从日志解析原理到 KFS 同步链路搭建(含建表与增删改查完整代码)
数据库·oracle·信创·数据集成·国产数据库·kingbasees·全量+增量同步
程序员塔塔喵10 小时前
【MySQL篇|第七篇】MySQL事务
数据库·mysql·mysql事务
独隅11 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
_孤傲_11 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
数字新视界13 小时前
一体化机柜在数据中心运维中的创新应用与优势分析
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
SelectDB13 小时前
从 StarRocks 走向 Apache Doris:如何实现引擎平滑替换与架构升级?
大数据·数据库·数据分析
为思念酝酿的痛13 小时前
MySQL的操作
数据库·mysql
猫咪很可爱13 小时前
Oracle ORA-4031 错误分析与处理:SGA 内存不足导致 update/exp/expdp 失败
数据库·oracle