linux cpu高需分层定位:先看top中%cpu(s)各字段(us/sy/wa/st/id)判断耗时类型;再用ps或top找高cpu进程;接着用top -hp或perf/jstack下钻线程与调用栈;最后用mpstat、vmstat交叉验证并限流缓解。

Linux CPU利用率过高,关键不是“看哪个进程占得多”,而是分清CPU时间花在了哪里:是程序在拼命算(user),还是内核在忙调度/中断(sys),又或是干等着磁盘响应(wa),甚至被虚拟机宿主抢走了(steal)。定位瓶颈要按层次推进,从系统整体到单个线程再到具体函数。
第一步:看清CPU时间都去了哪儿
运行 top -b -n1 | head -n5,重点关注 %Cpu(s) 这一行:
- us(user)高 → 应用层代码计算密集,比如死循环、低效算法、未缓存的重复计算;
- sy(system)高 → 内核开销大,常见于频繁系统调用、大量上下文切换、网络/磁盘驱动处理压力大;
- wa(iowait)高 → CPU在等I/O完成,但此时进程常处于 D 状态(不可中断睡眠),不是真忙,是空等,需查磁盘或存储链路;
- st(steal)高 → 云环境常见,说明宿主机把本该给你的CPU时间分给了其他虚拟机,联系云厂商或扩容实例;
- id(idle)持续低于5% 且 us/sy 同时高,才说明CPU真正饱和。
第二步:锁定是哪个进程在拖累CPU
在 top 中按 Shift+P 按CPU使用率降序,或直接执行:
ps aux --sort=-%cpu | head -n 8
重点关注三列:PID(进程号)、%CPU(占用率)、COMMAND(进程名)。若看到 java、python、nginx、php-fpm、mysqld 等业务进程长期超70%,基本就是它;若全是内核线程(如 ksoftirqd、kworker)或 systemd-journald 占高,则倾向内核或日志写入问题。
第三步:深入到线程与调用栈
对高CPU进程进一步下钻:
- 查该进程所有线程: top -Hp [PID] 或 ps -mp [PID] -o THREAD,tid,time | sort -rn;
- 取最高耗时线程的 TID(显示为 PID 列),转成小写十六进制:printf "%x\n" [TID];
- 如果是 Java 进程:jstack [PID] | grep -A 10 "[十六进制TID]",看堆栈里卡在哪行代码、什么方法、是否死循环或锁竞争;
- 非 Java 进程(如 C/C++、Go):perf record -g -p [PID] -a sleep 10,再执行 perf report -n --no-children,可直观看到热点函数和调用链。
第四步:辅助验证与快速缓解
别只盯着一个命令反复刷屏,搭配使用能交叉印证:
- mpstat -P ALL 1:看各CPU核心是否严重不均衡(某核99%、其余全闲),可能是线程绑定或负载分发问题;
- vmstat 1:观察 cs(context switch) 是否异常高(>10万/秒),暗示线程/进程过多或锁争用;
- 应急时可先限流:nginx 配置 limit_req,或用 cgroups 临时限制进程CPU配额;
- 确认无误后,优先考虑降级非核心功能、重启异常进程、升级补丁或调整JVM参数(如GC策略),而非立刻加机器。










