Java应用CPU过高通常因线程RUNNABLE状态死循环或JVM频繁GC;排查路径为:top定位高CPU进程→top -H锁定高耗线程→jstack映射堆栈定位代码行。

Java 应用 CPU 占用过高,90% 以上情况集中在两类:线程处于 RUNNABLE 状态持续执行(比如死循环、密集计算),或 JVM 频繁 GC 消耗大量 CPU。命令行排查的核心路径是:**定位高 CPU 进程 → 锁定高消耗线程 → 映射到 Java 堆栈 → 定位具体代码行**。整个过程无需重启、不依赖图形界面,适合生产环境快速响应。
查进程:确认是不是 Java 进程在吃 CPU
先运行 top,看整体负载和占用最高的 PID:
- top —— 查看全局 CPU 使用率,重点关注 %CPU 列;若某进程长期 >100%,说明它跨核占用多 CPU 时间
-
top -c —— 显示完整命令行,可确认该进程是否为
java -jar xxx.jar或其他 JVM 启动方式 - ps -ef | grep java —— 快速列出所有 Java 进程及其 PID,避免被同名非 Java 进程干扰
查线程:找到真正“跑飞”的那个线程
Java 进程本质是多线程运行,单个线程卡在死循环就能拉满一个 CPU 核。用 top -H 查看线程级资源消耗:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- top -H -p <PID> —— 只监控指定 Java 进程下的所有线程,按 %CPU 排序,一眼识别出占用最高的线程 ID(TID)
- 记下高 CPU 的 TID(十进制),例如 12345
- 转成十六进制:printf "%x\n" 12345 → 输出 3039(jstack 中线程标识
nid=0x3039就靠它)
查堆栈:把线程状态和代码行对应起来
用 jstack 抓取当前所有线程快照,重点找 RUNNABLE 状态且匹配 nid 的线程:
立即学习“Java免费学习笔记(深入)”;
-
jstack <PID> > threaddump.log —— 导出完整线程快照(注意:JDK 8+ 默认不带时间戳,建议加
-l参数显示锁信息) - 在文件中搜索 nid=0x3039,定位到对应线程块
- 看关键两行:
java.lang.Thread.State: RUNNABLE(说明它真正在干活,不是等锁或睡眠)at com.example.MyService.loopForever(MyService.java:42)(直接指向问题代码行) - 常见死循环特征:
while(true)、空for(;;)、未更新的循环变量、正则匹配超时未设 limit、递归无出口等
排除 GC 干扰:确认不是垃圾回收拖垮 CPU
如果多个线程都显示 VM Thread 或 GCTaskThread 占 CPU 高,或堆内存使用率逼近上限,就要查 GC 是否异常:
-
jstat -gc <PID> 2000 —— 每 2 秒刷新一次 GC 统计,重点关注:
YGC/FGC(次数是否突增)、YGCT/FGCT(单次耗时是否超 100ms)、S0U/S1U/EU/OU(各区使用率是否长期 >90%) - 配合 jmap -histo:live <PID> | head -20 —— 看存活对象里有没有异常膨胀的类(如
[B字节数组、HashMap$Node、自定义缓存容器),这往往是内存泄漏或数据加载失控的信号 - 若确认是 GC 导致,再结合 GC 日志(需提前开启
-Xloggc:gc.log -XX:+PrintGCDetails)分析触发原因

















