服务器内存过高排查流程

服务器内存过高排查流程

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

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 看全局排行,避免只盯一个进程、忽略真正的大头。

相关推荐
ClouGence1 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将3 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_2 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
冬奇Lab6 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence6 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神6 天前
三、用户与权限管理
数据库·mysql
麦聪聊数据7 天前
数据服务化时代:企业数据能力输出的核心路径
数据库