CPU 飙高该如何排查

CPU 飙高排查我一般分三步:

第一:确认是用户态还是系统态高,用 top 看 us/sy/wa

第二:定位具体进程,再定位线程

第三:结合线程栈分析是死循环、锁竞争、GC 频繁还是线程过多

1)us 高、sy 低、wa 低

含义:纯用户态计算,无阻塞、无系统调用、无 IO

典型原因

  • 死循环
  • 复杂计算 / 递归
  • JSON / 序列化疯狂
  • 正则回溯爆炸
  • GC 线程疯狂(VM Thread、GC task)

栈特征大量 RUNNABLE,一直占 CPU 不释放

一句话

us 高 sy 低 = 业务代码死循环 / 计算密集 / GC 频繁,直接 jstack 找 RUNNABLE 栈。

2)sy 高、us 低 / 一般

含义:内核态繁忙,系统调用频繁

典型原因

  • 线程频繁切换(thread count 极高)
  • 大量网络 IO:accept/read/write 太多
  • 大量锁竞争(mutex、自旋锁)
  • 大量小 IO、频繁系统调用

栈特征

  • RUNNABLE 但在native 方法
  • epollWaitreadwritelock
  • 大量线程 WAITING / BLOCKED

一句话

sy 高 = 线程太多、切换频繁、锁竞争、网络 IO 密集,看线程数 + 锁。

3)wa 高(iowait 高)、us/sy 都不高

含义:CPU 空闲,但在等磁盘 IO

典型原因

  • 磁盘满、磁盘慢
  • 大量日志打印、文件读写
  • SQL 慢查询(大量物理 IO)
  • 大量阻塞 IO(InputStream、FileWriter)

栈特征

  • 大量 RUNNABLE 但卡在 IO
  • readwriteFileInputStream
  • 数据库驱动 socketRead0

一句话

wa 高 = 不是 CPU 问题,是 IO 瓶颈:磁盘慢 / 日志多 / 慢 SQL。

4)锁竞争严重(sy 略高、us 一般、线程 BLOCKED 多)

特征

  • 锁等待多,CPU 不极端高,但应用极慢
  • BLOCKED 大量出现
  • 大量线程等待同一把锁:waiting to lock <0x...>

典型原因:synchronized 竞争、ReentrantLock 抢锁严重

一句话

大量 BLOCKED = 锁冲突,找占有锁的线程,优化锁粒度或无锁。

5)GC 频繁导致 CPU 飙高

特征

  • us 高,但不是业务线程
  • jstack 看到:VM ThreadGC task thread#0
  • jstat -gc 看到 YGC 每秒多次、FGC 频繁

原因:内存不足、大对象、内存泄漏

一句话

GC 线程占 CPU = 内存问题,不是业务代码死循环。

6)线程数过多导致 CPU 高

特征

  • sy 明显高
  • ps -eLf | grep java | wc -l 几千线程
  • 大量 TIMED_WAITING、WAITING
  • 频繁线程切换消耗内核 CPU

原因:线程池无限制、new Thread 滥用、定时任务太多

一句话

线程数过多 → sy 高、吞吐低,限制线程池核心线程数。

三、终极面试万能口诀(背这个就行)

  • us 高:死循环、计算密、GC 疯
  • sy 高:线程多、切换频、锁竞争
  • wa 高:IO 慢、磁盘忙、慢查询
  • BLOCKED 多:锁冲突
  • GC 线程高:内存炸
  • 线程几千:池无限
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务