线上cpu飙高排查步骤:
方法一 :
- top命令查看进程与CPU的使用情况
- 判断是否GC导致CPU冲高, 主要看GC频率和内存使用情况, 具体命令可参考: jvm常用指令
- 如果不是GC问题, top -Hp PID 查看占用CPU最高的进程的线程情况
- 确定线程后,计算线程ID对应的十六进制值: printf "%x\n" <java_thread_id>
- 将该线程堆栈内容输出: jstack <java_pid> | grep <线程id十六进制值> -A 30 【-A 30表示向下打印30行】, 这时就可以看到业务代码中那一部分使CPU飙高了。这里的信息可以精确到java代码的类、方法、行数:
- 根据第三步的结果, 修改业务逻辑代码
方法二:
1、导出方法一中的线程对应的堆栈信息:
jstack PID > stack.text
2、将导出的文件上传到: gceasy.io/ft-index.jsp Smart Java thread dump analyzer - thread dump analysis in secondsFree online thread dump analyzer to troubleshoot Java, android applications. Kotlin, Clojure, Scala, Jruby, Jython, all JVM language thread dumps are supported. hs_err_pid, core dump files are analyzed.https://gceasy.io/ft-index.jsp
上传完成后,会对文件的进行分析,得到下面的信息:
top命令及参数说明:
1、线上CPU使用情况查看: top命令
上图中,我的top命令输出的结果的与你们的输出结果是不是不太一样,我的字体是红色,而且展示了cpu的个数和每个的私用情况, 还有就是内存的使用是一个图形结构。 而你们的top命令截图应该是下面这样的:
这需要记住几个按键和作用:
- 按z可更改top追踪的颜色
- 按1键可查看系统上每个 CPU 内核的图形表示
- m键以图形方式显示内存使用情况
- t 图形的方式显示CPU使用情况
1.1 top参数信息
- up *** days, *** min :说明此服务器连续运行 *** 天 *** 分钟
- *** users : 当前登录用户数
- load average:***, ***, *** : 系统负载,即任务队列的平均长度。三个数值分别为1分钟、5分钟、15分钟前到现在的平均值
1.2 Tasks 系统任务
- total:总进程数
- running: 正在执行进程数
- sleeping :正在休眠进程数
- stoped : 暂停进程数
- zombie: 僵尸进程数
1.3 %Cpu 系统CPU使用情况
- us : 系统用户占用比例
- sy: 系统内核占用比例
- ni: 优先级调度占用比例
- id:空闲CPU
- wa: I/O 等待占用比例
- hi:硬件中断占用
- si:软件中断占用
- st:虚拟化占用
1.4 Kib Mem 系统内存使用情况
- total:总内存空间
- free:空闲内存
- used:已用内
- buff/cache:物理内存和交换内存的缓冲区总和。
1.5 Kib Swap 系统交换空间使用情况
- total:总交换空间
- free:空闲交换空间
- used:已用交换空间
- avail Mem:可用物理空间。
1.6 运行进程信息, 也是我们最常使用的数据
- PID: 进程ID
- USER: 进程所有者
- PR: 优先级
- NI: 进程优先级
- VIRT: 虚拟内存
- RES: 实际使用的物理内存
- SHR: 共享内存大小
- S: 进程状态(D=不可中断的睡眠状态,R=运行中或可运行,S=睡眠中,T表示已跟踪以及已停止,Z=僵停
- %CPU: 上次更新到现在的cpu时间占用百分比
- %MEM: 进程使用的物理内存百分比
- TIME+: 进程使用的cpu时间总计
- COMMAND: 命令名/命令行
2. top命令常用参数 :分析具体线程 top -Hp PID
- 1. H:显示线程
- 2. p:根据CPU使用百分比大小进行排序。
使用top -Hp PID 命令后,显示的信息与top 命令有一些不同: 这里没有了Task 而是展示了 Threads, 标识当前进程中总共有多少个线程。
参考文档: