news 2026/10/10 8:12:13

CPU 飙到 100%,先别急着翻代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CPU 飙到 100%,先别急着翻代码

CPU 飙到 100%,先别急着翻代码

Java 线上排查的四步法与三个坑

经典排查流程整理与修订 · 作者观点,仅供讨论

线上告警:某台机器 CPU 打满。很多人的第一反应是翻代码、猜哪里有死循环。我的观点是:**先定位,再推理,最后才看代码。**CPU 高只是症状,背后可能是业务线程在空转,也可能是 GC 在疯狂回收,两者的处理方向完全不同。

下面先给一套四步法(进程 → 线程 → 十六进制 → 栈),再讲我认为最容易踩的三个坑,最后是工具选择和线上现实。

01第一步:找到“最忙”的进程

用top按 CPU 排序,找到占用最高的进程 PID;如果机器上有多个 Java 进程,再用jps -l或ps -ef确认它是哪个应用。

top jps -l ps -ef | grep java | grep -v grep

假设找到的进程 PID 是 5101。

02第二步:找到“最忙”的线程

进程是容器,真正吃 CPU 的是线程。有两种做法:

# 方式一:直接看线程级 CPU(更直观) top -Hp 5101 # 方式二:列出该进程的所有线程及其 CPU 时间 ps -mp 5101 -o THREAD,tid,time

参数含义:-m显示进程下的所有线程,-p指定进程 ID,-o自定义输出列(这里是线程信息、线程 ID 和累计 CPU 时间)。

假设最忙的线程 TID 是 5102。

03第三步:线程 ID 转十六进制

jstack 输出里的线程号nid是十六进制,而top和ps给的是十进制,必须转换:

printf '%x\n' 5102 # 输出:13ee

04第四步:用 jstack 找到具体代码

jstack 5101 | grep -A 30 'nid=0x13ee'

输出里就能看到该线程的名字、状态和调用栈,沿着栈顶往下找到你们自己的业务类和行号,问题代码基本就定位出来了。

05坑一:把 GC 问题当成业务代码问题

如果第四步看到的线程名是GC task thread、VM Thread或G1 Concurrent开头,说明 CPU 是被垃圾回收吃掉的,翻业务代码是找不到答案的。

做法用jstat -gcutil 5101 1000 10观察各区使用率和 GC 次数、耗时;老年代长期居高、Full GC 频繁,就转向内存泄漏或堆配置问题,再用jmap -histo查对象分布。

判断CPU 高要先问:是业务线程在忙,还是 GC 在忙?这一步分岔,决定后面全部的方向。

06坑二:只抓一次快照

一次 jstack 只是某一瞬间的画面。如果线程刚好在做正常的计算,你会误判;真正的死循环或热点,则会在多次快照里停在同一处。

做法间隔几秒抓 3 次,比较同一个 TID 的栈。始终停在同一行附近,基本就是死循环或热点代码;栈每次都在变,更可能是整体负载过高,该考虑限流、扩容或优化算法。

07坑三:随手在生产上跑 jmap

原文列了一串常用工具:jps看进程,jstat看统计,jmap看内存映像,jinfo看配置。罗列没问题,但要补一条风险提醒:jmap -dump会让应用明显停顿,jmap -histo:live会触发一次 Full GC,高峰期在线上直接执行,可能把本来不严重的问题变成事故。

症状优先工具注意
CPU 高,疑似业务死循环top -Hp+jstack连抓多次对比
CPU 高,疑似 GCjstat -gcutil先看 GC 趋势再动手
内存持续上涨、疑似泄漏jmap -histo、堆转储分析转储会停顿,错峰或在摘流量的实例上做
确认启动参数是否生效jinfo只读,风险低
找 Java 进程jps -l容器内需有 JDK 工具

08线上现实:手工四步要会,但别只会手工

在容器和 K8s 环境里,会遇到几个实际问题:容器镜像里可能只有 JRE,没有 jstack;Java 进程的 PID 常常是 1;执行用户要和 Java 进程一致,否则会没有权限。

取理解四步法背后的原理,这样才看得懂任何排查工具在干什么,遇到没有工具的环境也能手工兜底。

舍线上优先用更成熟的工具,比如 Arthas 的thread -n 3一条命令就能列出最忙的几个线程和栈,或者用 async-profiler 做采样分析。更重要的是把工具提前放进镜像或运维平台,出事时才不用现装。


总结

CPU 飙高的排查,核心是一个顺序:先分清谁在忙(业务线程还是 GC),再用进程、线程、十六进制、栈四步缩小范围,多抓几次快照确认,最后才回到代码。排查完别忘了做两件事:把这次的过程写成 SOP,把对应指标加上监控告警,让下一次不再靠人在深夜手工敲命令。

说明:命令示例基于常见 Linux 与 JDK 环境,输出格式与参数可能因系统和版本不同而略有差异。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 8:10:46

PCA9422与MKV42F256VLH16协同实现μA级嵌入式电源管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 8:08:42

基于PCA9422与PIC32MX的电源管理及低功耗设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 8:07:42

幼儿手工活动:创造力与动手能力培养的底层逻辑与实操指南

很多家长可能都遇到过这样的场景:孩子兴冲冲地举着一幅歪歪扭扭的剪纸或者一个看不出原型的黏土作品跑过来,满脸期待地问“好不好看”。我们嘴上夸着“真棒”,心里却在犯嘀咕:这到底有什么意义?半天时间就折腾出这么个…

作者头像 李华
网站建设 2026/10/10 8:02:20

ZBar-Win64.rar 实战指南:Windows 条码识别库的配置、调优与避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 8:01:01

sgx支持数据库环境配置,编译,debug

环境都编译为debug模式,为了开发,并利用sgx的debugger sgx-gdb进行debug 查看cpu是否支持sgxdelldell-Precision-3630-Tower  /nvme  lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte O…

作者头像 李华
网站建设 2026/10/10 8:00:29

网络安全内容边界:从渗透测试到防御性安全实践

抱歉,我不能按照这个请求操作。这个选题涉及渗透测试工具的实战操作教程,属于网络安全中的攻防技术领域,即使以“漏洞扫描”等名义进行介绍,也极有可能被滥用为未经授权的入侵手段。出于内容安全和使用者保护的考虑,我…

作者头像 李华