JAVA服务问题诊断

发布时间:2026/8/22 10:23:41
JAVA服务问题诊断 第一步定性 — 确认故障类型先看监控大盘Grafana / Prometheus / SkyWalking 等确认故障属于哪一类CPU 持续飙高内存持续增长 / OOM频繁 Full GC接口响应慢 / 超时线程阻塞 / 死锁定性决定了后续排查方向避免上来就盲猜。第二步定位异常进程# 查看整机资源占用找到异常 Java 进程 PID top -c # 或者只看 Java 进程 jps -l如服务器4核可以看到253533的进程cpu使用率高。第三步根据故障类型分流排查场景一CPU 飙高# 1. 找到进程内哪个线程最耗 CPU top -H -p PID # 2. 将高 CPU 线程的 TID 转为十六进制 printf %x\n TID # 3. 导出线程堆栈搜索该 nid jstack -l PID thread.log grep -A 30 nid0x十六进制TID thread.log判断要点堆栈停在业务代码且状态为RUNNABLE→ 死循环、复杂计算、正则回溯堆栈停在 GC 相关方法 → 频繁 GC 导致转场景二大量线程BLOCKED→ 锁竞争查waiting to lock和locked关键技巧间隔 3~5 秒连续抓 3 次 jstack如果某线程 3 次都停在同一行代码说明确实卡死如果一直在变说明只是执行慢。jstat -gcutil是 Java 虚拟机JVM中用于监控垃圾回收GC状态的命令行工具其输出以百分比形式展示各内存区域的使用率便于快速判断 JVM 内存健康状况。该命令不会触发 GC也不会挂起应用非常适合线上环境实时观察。各列含义及正常范围参考如下S0 / S1Survivor 区使用率两个 Survivor 区交替使用正常情况下一个为 0%另一个在 0%~100% 之间波动。若两者同时高或长期为 0%可能 Survivor 区配置过小或对象晋升过快。EEden 区使用率正常应在 0%~95% 之间波动。若持续 95% 且频繁 Young GC说明对象分配速率过高或 Eden 区过小。O老年代使用率健康范围通常在 30%~70%。超过 70% 需警惕超过 85% 且持续上升极可能即将触发 Full GC。MMetaspace 使用率应稳定在 80%~95%。若长期 90% 且持续增长可能存在类加载泄漏或元空间配置不足。CCS压缩类空间使用率与 Metaspace 相关通常与 M 列趋势一致若异常升高也需关注类加载问题。YGC / YGCTYoung GC 次数与总耗时次数随运行时间增长属正常单次耗时一般 0.01s 为良好。若 YGCT 增长过快说明 Young GC 频繁或效率下降。FGC / FGCTFull GC 次数与总耗时理想状态为 0。若 FGC 0 且 FGCT 持续增长说明系统已出现内存压力需立即排查。GCT总 GC 耗时等于 YGCT FGCT用于评估整体 GC 开销。示例截图场景二内存泄漏 / 频繁 Full GC# 1. 实时观察各区域使用率百分比直观 jstat -gcutil PID 1000 # 2. 查看堆内存概要 jmap -heap PID # 3. 查看哪些对象实例最多 jmap -histo PID | head -20 # 4. 导出堆快照建议在低峰期执行会触发 STW jmap -dump:live,formatb,fileheap.hprof PID拿到heap.hprof后用Eclipse MAT打开分析查看Dominator Tree支配树找到占用内存最大的对象查看Leak Suspects泄漏嫌疑MAT 会自动分析可疑泄漏点追踪GC Root 引用链定位是哪段代码持有了对象导致无法回收常见根因静态集合如static List不断往里塞对象连接 / 流未关闭线程池未销毁一次性加载全表数据未分页缓存无上限、无过期策略示例截图使用mat分析既然MemoryLeakBug占用了 402MB它内部一定有个巨大的集合或数组。在 MAT 的Dominator Tree支配树视图中找到最大的com.demo.bugs.MemoryLeakBug实例。场景三服务假死CPU 不高但接口全超时# 导出线程堆栈 jstack -l PID thread.log # 统计线程状态分布 grep java.lang.Thread.State thread.log | sort | uniq -c # 检测死锁 grep -i deadlock thread.log如果大量线程处于WAITING/BLOCKED说明线程都在等资源数据库连接、Redis、第三方接口、锁等顺着堆栈找等待的具体资源即可。第四步Arthas 加速排查推荐如果线上允许安装Arthas 可以大幅简化排查# 安装并启动 curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar # 常用命令 thread -n 3 # 直接看 CPU 最高的 3 个线程堆栈 thread -b # 一键检测死锁 trace 包名.类名.方法名 # 追踪方法内部各步骤耗时定位慢接口 watch 包名.类名.方法名 # 监控方法入参、出参、异常 heapdump --live /tmp/heap.hprof # 导出存活对象堆快照第五步日志交叉验证根据 jstack 堆栈中的代码行号去业务日志中搜索对应时间点的日志还原故障触发场景确认是哪次请求、哪个参数导致的问题。快速对照表表格故障现象核心命令常见根因CPU 飙高top -H -pjstack死循环、正则回溯、频繁 GC内存持续增长jstat -gcutiljmap -histo静态集合泄漏、连接未关闭频繁 Full GCjstat -gcutil MAT 分析老年代满、大对象、内存泄漏服务假死jstackgrep BLOCKED死锁、锁竞争、外部资源超时接口响应慢Arthastrace慢 SQL、缓存失效、下游超时排查口诀top 找进程 → top -H 找线程 → jstack 看代码 → jstat 看 GC → jmap 看内存 → MAT 找泄漏掌握这套流程绝大多数线上 Java 故障都能在几分钟内定位到根因。