真实面经题目 · 原创解析

常见的cpu load过高,us过高,一般是什么问题?

CPU load 高和 CPU 使用率高不是同一个概念。load average 统计可运行队列和不可中断 I/O 任务,us 高表示用户态代码消耗大量 CPU。排查要先看 us、sy、wa、si、st 的结构,再定位到进程、线程和调用栈。

出现于:阿里巴巴 · 算法

60 秒回答模板

我会先区分 load average 和 CPU usage。load average 表示一段时间内处于可运行状态或不可中断 I/O 状态的任务平均数,要和 CPU 核数一起看;CPU usage 表示 CPU 时间分布,常见字段有 us、sy、wa、si、st。常见的 load 高且 us 高,通常说明大量线程真的在用户态跑 CPU,原因可能是热点算法、死循环、自旋、线程池过大、频繁 GC、序列化反序列化、正则回溯、压缩、加解密等。排查路径是先用 uptime 看 1、5、15 分钟趋势并和核数比较,再用 top 看整体 CPU 构成和高 CPU 进程,用 vmstat 看 r 队列、b 队列、上下文切换和中断,用 pidstat 或 top -H 定位到进程和线程。Java 服务还要把线程 id 转成十六进制,对应到 jstack 的 nid 找具体栈;native 或混合场景可以继续用 perf 定位热点函数。如果 wa 高,优先查磁盘、数据库或网络存储;如果 sy 高,查系统调用、锁竞争和上下文切换;如果 si 高,查网络软中断;如果 st 高,查虚拟化资源抢占。

考点 概念区分
主线 us 过高
易错点 把 load average 直接当 CPU 使用率,…

深入解析

01

概念区分

load average 不是 CPU 使用率,而是平均活跃任务数,包含正在运行、等待 CPU 运行和不可中断 I/O 的任务。CPU usage 则是 CPU 时间花在哪里的比例。面试中先把这两个概念分开,能避免把所有 load 高都误判成 CPU 算力不够。

02

us 过高

us 表示用户态 CPU 时间。us 高通常说明应用代码本身在消耗 CPU,常见原因包括死循环、复杂算法、正则灾难回溯、JSON 序列化、压缩、加解密、频繁 GC、线程自旋、线程池过大导致大量可运行线程争抢 CPU。

03

其他字段

sy 高偏向内核态开销,常见于系统调用密集、锁竞争、上下文切换过多、网络或文件操作频繁。wa 高说明 CPU 等 I/O,可能是磁盘、数据库、网络存储慢。si 高偏网络软中断或包处理压力,st 高说明虚拟机 CPU 被宿主机抢占。

04

队列判断

vmstat 中 r 表示等待或正在运行的任务数,长期大于 CPU 核数通常说明 CPU 排队严重;b 表示不可中断睡眠任务,b 高通常和 I/O 阻塞有关。load 高时结合 r 和 b,才能判断是 CPU 密集还是 I/O 堆积。

05

定位链路

基础路径是 uptime 看趋势,top 看 CPU 构成和进程,vmstat 看 r、b、cs、in,pidstat 看进程或线程级 CPU。Java 场景用 top -H 找高 CPU 线程,将线程 id 转十六进制后在 jstack 中匹配 nid,再分析具体代码栈。

06

工程处置

如果定位到业务热点,要优化算法、减少重复计算、控制批量大小或缓存结果;如果是 GC,要看堆、分配速率和对象生命周期;如果是线程池,要调整并发度和队列策略。不能只凭 load 高就扩容,否则可能掩盖根因。

易错点

  • 把 load average 直接当 CPU 使用率,不看核数和任务状态。
  • 看到 us 高就直接扩容,不定位进程、线程和调用栈。
  • wa 高时仍按 CPU 密集问题处理,忽略 I/O 阻塞根因。
  • 只看 top 某一秒输出,不观察 1、5、15 分钟趋势。
  • Java 场景不会把线程 id 转十六进制,导致 jstack 对不上。

面试官追问

load 高但 CPU 使用率不高,可能是什么原因?

常见是不可中断 I/O 任务堆积,例如磁盘慢、网络存储慢、数据库响应慢、文件系统阻塞。此时 vmstat 的 b 和 iostat、磁盘延迟指标会比单看 top 更关键。

us 和 sy 都高时怎么区分问题?

us 高说明应用用户态逻辑重,sy 高说明内核态开销重。可以结合 perf、strace、上下文切换、系统调用频率、锁竞争和网络包量来判断是业务计算还是内核路径消耗。

Java 高 CPU 怎么定位到具体代码?

先用 top -H 或 pidstat 找到高 CPU 线程,再把十进制线程 id 转为十六进制,在 jstack 输出里按 nid 查找对应线程栈,最后结合多次采样判断稳定热点。

线程数过多为什么会让 CPU load 升高?

大量线程处于可运行状态会增加运行队列长度,也会带来调度、上下文切换和锁竞争成本。即使每个线程做的事不重,总体也可能把 CPU 时间消耗在争抢和切换上。