260104-JVM面试题

Java并发编程面试题

线上服务CPU飙高,你如何排查?请描述完整的调优流程

总体思路采用 止血 ——> 定位 -> 分析 -> 修复 -> 发布验证 -> 复盘

止血

  1. 通过监控大盘,迅速是哪些节点的服务有问题;查看系统load、sys(上下文切换、锁竞争、频繁内核调用)、user(业务计算)、wait(io阻塞)
  2. 查看系统Load Average 是否远超CPU核数限制、结合vmsataus 1 5 查看 cs(上下切换)、si/so 交换内存、
  3. 紧急措施:网关限流/降级非核心链路、动态扩容,必要时摘除故障节点并重启

精确定位高CPU线程

1
2
3
4
5
6
7
8
9
10
11
12
# ① 找高 CPU 进程
top # 按 P 排序,记录 PID

# ② 找该进程下高 CPU 线程
top -Hp <PID> # 或 pidstat -t -p <PID> 1 5
# 记录占用最高的 TID(如 12345)

# ③ TID 转 16 进制(jstack 需要)
printf "%x\n" 12345 # 输出 3039

# ④ 抓取该线程堆栈
jstack <PID> | grep 3039 -A 20

或者使用 arthas, thread -n 5 直接找出cpu过高的线程

原因分析

状态 典型原因 验证手段
RUNNABLE 死循环、复杂正则、大量计算、序列化/反序列化、频繁 Full GC jstat -gcutil 1s 看 GC 频率
BLOCK/WAITING 线程锁竞争、连接池耗尽、同步 I/O 阻塞 jstack 找 waiting to lock;检查 DB/Redis 慢查询或连接配置
Sys CPU 占比高 频繁上下文切换、大量短连接、锁自旋、驱动/网络中断 pidstat -w 1、sar -W 1、检查 net.core.somaxconn/tcp_tw_recycle

修复 & 调优

代码层:修复死循环/正则、改用异步处理、优化算法复杂度、分页/流式导出。
JVM 层:调整 GC 参数(如 G1 MaxGCPauseMillis)、调大年轻代减少 Minor GC、排查内存泄漏。
架构层:日志改异步(Log4j2 AsyncAppender)、报表走离线数仓、引入缓存/读写分离。

验证 & 预防

灰度发布后观察 CPU/RT/QPS/错误率曲线。
补充监控告警:CPU 持续 >80% 超 3min 触发告警;配置线程池/连接池监控。
输出复盘报告:根因、影响面、改进项、压测基线。

其他

区分 Load Average 和 CPU Usage:Load 高不一定是 CPU 问题,可能是 D 状态进程(I/O 阻塞)。
提一嘴火焰图:async-profiler 或 Arthas profiler 生成火焰图,能直观看到 CPU 热点方法链,比纯看 jstack 更高效。
强调生产安全:线上不盲目 kill -3 或频繁 jstack,优先用 Arthas、pidstat、监控大盘无损排查。
闭环思维:排查不是目的,建立基线监控、压测标准、容量规划才是工程化价值。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×