Java 性能调优实战:CPU 飙高、频繁 GC 与内存泄漏排查
本文总结了 Java 开发中常见的性能问题实战案例,涵盖从场景到代码的排查与优化方案。
Top1:CPU 使用率飙高
核心信息
问题:Java 进程 CPU 使用率突升至 90%+,应用响应缓慢、接口超时
场景:电商秒杀、高频接口调用、实时数据计算等高并发场景
成因:1. 无限循环/高频循环(无阻塞/休眠);2. 频繁 GC(垃圾回收线程占满 CPU);3. 锁竞争激烈导致线程频繁切换;4. NIO 空轮询(JDK 早期 bug)
实战案例
某电商平台秒杀活动,开抢后 3 分钟接口响应从 200ms 飙升至 2s+,监控显示 Java 进程 CPU 达 95%,部分用户下单失败。
调优步骤
- 定位高 CPU 进程:执行命令
top,找到 CPU 占比最高的 Java 进程(记 PID,如 5678) - 定位高 CPU 线程:执行
top -H -p 5678,找到占比最高的线程(记 TID,如 5679) - 线程 ID 转十六进制:执行
printf "%x\n" 5679,得到结果 163b(jstack 日志用十六进制线程 ID) - 导出线程栈:执行
jstack 5678 > thread_dump.txt,搜索 163b 找到对应线程 - 分析问题:线程栈显示卡在
SeckillService.calculateStock()方法,排查发现循环内无限制计算库存,陷入高频循环
代码优化
优化前(高频循环):
// 秒杀库存计算方法,无循环限制,高频执行占满 CPU
public void calculateStock(Long seckillId) {
while (true) {
// 库存查询与计算,无阻塞/退出条件
Stock stock = stockMapper.selectById(seckillId);
if (stock.getCount() > 0) {
// 库存扣减逻辑
}
}
}
优化后(加循环限制 + 休眠):
public void calculateStock(Long seckillId) {
int loopCount = ;
() {
loopCount++;
stockMapper.selectById(seckillId);
(stock.getCount() > ) {
;
}
(loopCount % == ) {
{
Thread.sleep();
} (InterruptedException e) {
Thread.currentThread().interrupt();
;
}
}
(loopCount > ) {
log.error(, seckillId);
;
}
}
}


