CPU / 内存飙高了,先分清是“谁在吃”还是“被谁拖着”

举报
yd_228326260 发表于 2026/10/28 10:17:15 2026/10/28
【摘要】 CPU / 内存飙高了,先分清是“谁在吃”还是“被谁拖着”CPU 100% 和内存 90% 看起来都是“机器快不行了”,但成因完全不同:一个可能是某个进程真的在拼命算,一个可能是进程在等磁盘、等网络,CPU 空转着却被拖住;内存高可能是真的泄漏,也可能只是系统把空闲内存拿去做了缓存。先分清“谁在吃、吃的是什么、是突发还是持续”,再动手,免得杀错进程、重启错服务。 一、先看一眼全貌:是 CP...

CPU / 内存飙高了,先分清是“谁在吃”还是“被谁拖着”

CPU 100% 和内存 90% 看起来都是“机器快不行了”,但成因完全不同:一个可能是某个进程真的在拼命算,一个可能是进程在等磁盘、等网络,CPU 空转着却被拖住;内存高可能是真的泄漏,也可能只是系统把空闲内存拿去做了缓存。先分清“谁在吃、吃的是什么、是突发还是持续”,再动手,免得杀错进程、重启错服务。

一、先看一眼全貌:是 CPU、内存,还是负载

不要只看一个数字就下结论,先用三条命令定方向:

uptime
free -h
top -b -n 1 | head -n 20
  • uptime 里的 load average 是“排队等资源的进程数”,不是 CPU 使用率。单核机器 load 1 左右算正常,4 核机器 load 4 左右才算满载。
  • free -h 里要看 available,不是 free。Linux 会把空闲内存拿去做缓存(buff/cache),used 高不等于没内存可用,available 低才是真的紧张。
  • top 里 %CPU 超过 100% 不一定是异常:多线程进程会在多核上并行,200%、400% 都有可能,先看它占了几核、是不是一直在涨。

先回答三个问题:高的是 CPU 还是内存?是突然飙上去还是慢慢涨上去的?现在还在涨,还是已经稳定在一个高位?这三个答案决定后面查哪条线。

二、CPU 高:先定位到进程,再看它在干什么

按 CPU 占用排序,看看到底是谁:

ps aux --sort=-%cpu | head -n 10
pidstat -u 1 3
  • 某个业务进程长期占满单核:看它的日志和请求量,是不是某个慢接口、死循环、或者定时任务扎堆跑了。先查它在处理什么,再决定限流、修逻辑还是扩容。
  • 所有进程都不高,但 load 很高:看 top 里 %wa(iowait)是不是也高。iowait 高说明进程在等磁盘,瓶颈在磁盘不在 CPU,查磁盘那条线,别急着加核。
  • 云服务器上还要看 %st(steal time):宿主机资源争抢时,虚拟机会被“偷”走 CPU 时间。steal 长期偏高,先看实例规格和邻居争抢,别只在自己机器里找原因。
  • 短时冲高又回落:查定时任务和计划任务,crontab -l、systemctl list-timers --all,很多“每天固定时间卡一下”都是备份、日志轮转、定时脚本扎堆造成的。

杀进程之前先确认两件事:这个进程的父进程是谁(ps -o pid,ppid,cmd -p <PID>),以及它是不是被别的服务拉起来的。杀掉一个会被 systemd、supervisor 立刻拉起来的进程,等于白杀,还可能丢现场。

三、内存高:先区分缓存、泄漏和被撑爆

按内存占用排序:

ps aux --sort=-%mem | head -n 10
cat /proc/meminfo | grep -E 'MemTotal|MemAvailable|SwapTotal|SwapFree|Slab'
vmstat 1 5
  • available 还很充裕、只是 used 高:大概率是缓存,不用处理。可以用 echo 3 > /proc/sys/vm/drop_caches 验证是不是缓存,但这只是临时释放,不是根治办法,生产环境别当常规操作。
  • 某个进程的内存一直在涨、重启后又从低点重新涨:这才是泄漏的典型形态。看它的 RSS 变化趋势,配合应用日志,看是不是连接、缓存、队列没释放。
  • 内存和 Swap 一起被吃满:机器已经开始把内存往磁盘换,性能会断崖式下跌。先看是谁把内存撑爆的,再决定是扩内存、限流,还是给这个服务设上限:
# 以 systemd 服务为例,限制前先确认业务能接受被 OOM 杀掉的后果
[Service]
MemoryMax=2G
  • 有没有被 OOM killer 杀过,看内核日志最直接:
dmesg -T | grep -i 'oom\|killed process' | tail -n 20
journalctl -k --since "1 hour ago" | grep -i oom

被 OOM 杀掉的进程名和时间,是定位“到底是谁先把内存吃光”的关键证据,别只看事后残留的现场。

四、几个容易误判的点

  • load 高就加 CPU:load 高也可能是 iowait、不可中断睡眠(D 状态)进程排队造成的,加核解决不了等磁盘的问题。
  • 内存高就加内存:缓存高加内存没用,泄漏高加内存只是把崩溃时间往后推。先确认是缓存、泄漏还是突发流量,再决定加内存还是修代码、设上限。
  • 一上来就重启:重启能立刻降下来,但现场就没了。先抓一把快照再重启:top -b -n 1、ps aux、free -h、dmesg 的输出存下来,重启后对照着查。
  • 只看瞬时值:CPU 和内存都要看趋势。用 pidstat、vmstat、sar(如果装了 sysstat)连续采几组,或者看监控曲线,区分“一直高”“周期性高”“只高了一次”,三种的修法完全不同。

五、排查清单(收藏版)

  1. 高的是 CPU、内存,还是 load?uptime、free -h、top 先定方向。
  2. CPU 线:ps --sort=-%cpu 定位进程,pidstat 看趋势,%wa 高查磁盘,%st 高看云主机争抢。
  3. 内存线:ps --sort=-%mem 定位进程,available 低才是真的紧张,RSS 持续上涨才怀疑泄漏。
  4. 查历史证据:dmesg / journalctl -k 有没有 OOM 记录,定时任务有没有扎堆。
  5. 动手前先抓快照:top、ps、free、vmstat 的输出存下来,再决定杀进程、重启还是扩容。
  6. 治本再收尾:泄漏修代码、突发流量做限流、常驻服务设 MemoryMax 上限,别只靠重启续命。

CPU 查“谁在算、谁在等”,内存查“谁在占、占的是缓存还是泄漏”,分清再动手,大多数飙高都能在半小时内定位到具体进程和原因。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。