假如CPU占用较高,如何分析和定位?
答: 需要JDK命令&Linux命令结合分析
- top定位CPU占比较高的进程号pid;
- ps -ef 或者 jps 进一步定位,找出后台对应运行的程序 <—— ps -ef|grep java| gerp -v grep 或者 找出java进程 <——>jps -l
- 定位到具体线程或者代码 ps -mp 进程号 -o THREAD, tid, time
- 将需要的线程ID 转换为十六进制格式(英文小写格式) <—— printf %x\n 有问题的线程的ID
-
jstack 进程ID | grep tid(十六进制线程ID小写英文) -A60 A60<——> 打印前60行
第5步定位代码行号
创建了特别多的线程也会导致CPU使用率升高!
生产环境变慢,你的思路和性能评估?
整机: top
CPU: vmstat
内存: free <—— free m
硬盘: df <—— df -h
磁盘IO: iostat <—— iostat -xdk 2 3
网络IO: ifstat
top
主要查看%CPU
、%MEM
,还有load average
。load average
后面的三个数字,表示系统1分钟、5分钟、15分钟的平均负载值。如果三者平均值高于0.6,则 负载比较高了。当然,用uptime
也可以查看。
load average 高于60% 负载就很高了
查看CPU核心信息:
vmstat
查看进程、内存、I/O等多个系统运行状态。2表示每两秒采样一次,3表示一共采样3次。procs
的r
表示运行和等待CPU时间片的进程数,原则上1核CPU不要超过2。b
是等待资源的进程数,比如磁盘I/O、网络I/O等。
所有核信息,每2秒采样一次并打印
free 查看内存信息
pidstat -p 进程号 -r 采样间隔秒数
iostat -xdk 2 3
pidstat -d 2 -p 进程号
安装ifstat
查看网络IO
ifstat 秒数
找出CPU比较高的进程PID
top
打印该进程下线程的CPU占用比较高的tid
top -Hp {PID}
将该tid进行16进制转换id
printf "%x\n" {tid}
打印线程的堆栈信息
jstack {PID} |grep {id} -A 100
当然这四步的执行需要时间,但我们可以将这几步写成shell脚本来执行。
安装JDK命令行工具
服务器上安装的OpenJDK ,是否有常用的命令行工具?
验证是否安装
- [root@op-system ~]$ jstack -h
- Usage:
- jstack [-l] <pid>
- (to connect to running process)
- jstack -F [-m] [-l] <pid>
- (to connect to a hung process)
- jstack [-m] [-l] <executable> <core>
- (to connect to a core file)
- jstack [-m] [-l] [server_id@]<remote server IP or hostname>
- (to connect to a remote debug server)
如果输出如上内容表明,已经拥有工具,倘若没有,那么继续下面。
安装
- 查看JDK版本
- [root@op-system ~]$ java -version
- openjdk version "1.8.0_201"
- OpenJDK Runtime Environment (build 1.8.0_201-b09)
- OpenJDK 64-Bit Server VM (build 25.201-b09, mixed mode)
- 看openJDK有jstack的yum源
- [root@op-system ~]$ yum whatprovides '*/jstack'
- 1:java-1.8.0-openjdk-devel-debug-1.8.0.201.b09-2.el7_6.x86_64 : OpenJDK Development Environment 8 with full debug on
- Repo : @updates
- Matched from:
- Filename : /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64-debug/bin/jstack
找到和JDK版本对应的yum源。
- 安装
- [root@op-system ~]$ sudo yum install java-1.8.0-openjdk-devel-debug-1.8.0.201.b09-2.el7_6.x86_64
寻找问题所在
- 查出使用率最高的进程
- [root@op-system ~]$ top
发现 123067 这个进程特别消耗CPU。
- 查看进程中线程情况
- [root@op-system ~]$ top -p 123067 -H
发现 127510 这个线程特别消耗CPU,那么我们来看看这个线程到底是做什么的。
- 十进制id转十六进制
- [root@op-system ~]$ printf "%x\n" 127510
- 1eaec
- 使用jstack打印出线程的堆栈信息
- [root@op-system ~]$ jstack 123067 |grep 1eaec -A 100
从打印出来的信息中发现了很熟悉的代码,对,就是这里。
解决问题
那么既然找到了问题,我们就只能通过,数据库索引、SQL优化、算法优化、快速返回等方法来最这段代码优化了。