Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

  • JVM

    • JVM概述
    • JVM基础

    • 类加载机制

    • 运行时内存

    • 垃圾回收

    • 执行引擎与优化

    • 工具与问题排查

      • JVM参数
      • JDK命令行工具
      • jstack线程分析
      • jmap与堆转储分析
      • jcmd与JFR
      • CPU飙高排查
        • 1. 排查步骤
        • 2. 找 Java 进程
        • 3. 找高 CPU 线程
        • 4. 抓线程栈
        • 5. 常见原因
        • 6. GC 导致 CPU 高
        • 7. 多次采样
        • 8. 阶段小结
        • 9. CPU 高原因分类
        • 10. 排查命令串
        • 11. Tips 快问快答
      • 内存泄漏排查
      • 频繁Full GC排查
    • 调优实践与面试

目录

CPU飙高排查

Java 进程 CPU 飙高是常见线上问题。排查核心是找到哪个线程在消耗 CPU,再定位它正在执行什么 Java 代码。

# 1. 排查步骤

基本步骤:

  1. 找到 Java 进程 ID。
  2. 找到高 CPU 线程 ID。
  3. 转换线程 ID 为十六进制。
  4. 在线程 dump 中找到对应线程。
  5. 分析调用栈。
  6. 结合业务日志和监控确认原因。

# 2. 找 Java 进程

jps -l

或者:

ps -ef | grep java

假设进程 ID 是 12345。

# 3. 找高 CPU 线程

top -Hp 12345

找到 CPU 占用高的线程 ID,例如 12360。

转换为十六进制:

printf "%x\n" 12360

假设结果是:

3048

# 4. 抓线程栈

jstack -l 12345 > thread.dump

搜索:

nid=0x3048

查看该线程调用栈。

# 5. 常见原因

CPU 高常见原因:

  • 死循环。
  • 复杂正则。
  • 大集合排序或遍历。
  • JSON 序列化大对象。
  • 加解密或压缩。
  • 频繁 GC。
  • 锁竞争导致自旋。
  • 日志量过大。
  • 热点接口流量突增。

# 6. GC 导致 CPU 高

如果 CPU 高同时 GC 频繁,要看 GC 日志。

表现:

  • GC 线程占用 CPU。
  • 应用吞吐下降。
  • 老年代持续增长。
  • Young GC 或 Full GC 频繁。

这时需要分析对象分配和内存泄漏,而不是只看业务线程栈。

# 7. 多次采样

不要只抓一次线程栈。建议连续抓 3 到 5 次。

如果同一个线程总在同一段代码,说明它可能卡在热点逻辑。

如果每次不同,可能是整体负载高或采样不稳定,需要结合 JFR 或 profiler。

# 8. 阶段小结

CPU 飙高排查的关键链路是:进程 -> 线程 -> 十六进制 nid -> Java 调用栈 -> 业务原因。不要只看进程 CPU,也不要只猜 GC 或死循环,要用线程栈和监控建立证据链。

# 9. CPU 高原因分类

类型 特征 证据
业务死循环 单线程长期高 CPU 多次 jstack 同一栈
复杂计算 CPU 高但逻辑正常 profiler 热点方法
GC 繁忙 GC 线程占 CPU GC 日志频繁
锁自旋 CPU 高且锁竞争 JFR/线程栈
正则回溯 栈中 regex 方法 输入样本和正则
序列化大对象 JSON/序列化方法热 JFR 分配和 CPU

# 10. 排查命令串

jps -l
top -Hp <pid>
printf "%x\n" <tid>
jstack -l <pid> > thread.dump

如果 jstack 不能明确定位,继续:

jcmd <pid> JFR.start name=cpu settings=profile filename=/tmp/cpu.jfr duration=120s

# 11. Tips 快问快答

Q:CPU 高是不是一定要重启?

A:不一定。先判断是否影响服务和能否限流、隔离、关闭异常任务。重启前尽量保留线程栈或 JFR。

Q:单核满和整机满区别大吗?

A:很大。单核满可能是单线程死循环,整机满可能是并发流量、GC 或计算任务。

Q:为什么 CPU 高但线程栈看不出变化?

A:可能采样点不准、热点在 native、JIT 编译代码或多个线程分摊,需要 profiler。

Q:GC 导致 CPU 高怎么确认?

A:看 GC 日志频率、GC 线程 CPU、JFR GC 事件和应用吞吐下降。

上次更新: 2026/06/24, 16:03:01
jcmd与JFR
内存泄漏排查

← jcmd与JFR 内存泄漏排查→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式