线上问题排查实战

1,线上CPU突然升高

1.1 使用top命令

查看当前机器的cpu占比,进入top后,输入大写的P,进程按照CPU从高到底排序

1.2 使用 top -Hp PID

使用 top -Hp pid 查看当前进程下的所有线程使用cpu情况

前面的pid为当前线程号

1.3 将线程号转十六进制

使用 printf '%x\n' 线程号

看到当前线程转换后是7f7e,在该线程号前加上0x后0x7f7e就是jstack命令下的nid的

1.4 jstack查看线程号定位问题

jstack 17038 | grep '0x4295' -C10 --color

发现最耗CPU的线程是GC线程,继续使用jmap命令看当前进程的堆内存使用情况
jmap -heap pid

1.5 查看GC频率

查看gc频率的命令(其中O代表老年代占用率,FGC是FullGC次数,FGCT是fullGC时间;可以看出在频繁FullGC但是老年代有资源一直释放不掉)
其中17038为进程号,5000是指每5秒(5000毫秒)输出一次
jstat -gcutil 17038 5000

1.6 通过分析出问题时线上日志发现内存溢出;至此定位到问题根源是内存溢出导致(有未释放资源堆积,导致老年代被占满,然后频繁的FullGC但是资源一直释放不了)

2 造成原因

2.1 内存消耗过大,导致FullGC次数过多

造成FullGC原因:

  • 生成大量的对象,导致内存溢出-使用工具分析对象 查看具体内存对象占用情况。
  • 内存占用不高,但是Full GC次数还是比较多,此时可能是代码中手动调用 System.gc()导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

2.2 代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢

在1.4中可以定位到具体的线程和代码,是否是复杂算法或者无限循环导致

2.3 由于锁使用不当,导致死锁。

如果有死锁,在1.4 中会直接提示。关键字:deadlock.步骤四,会打印出业务死锁的位置。

2.4 随机出现大量线程访问接口缓慢。

代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;平时消耗的CPU不多,而且占用的内存也不高。

思路:

首先找到该接口,通过压测工具不断加大访问力度,大量线程将阻塞于该阻塞点

2.5 某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现;

执行步骤1-4:jstack多查询几次,每次间隔30秒,对比一直停留在parking 导致的WAITING状态的线程。例如CountDownLatch倒计时器,使得相关线程等待->AQS(AbstractQueuedSynchronizer AQS框架源码剖析)->LockSupport.park()。

posted @   浪成于微澜之间  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示