一、通过top命令定位占用cpu高的进程
执行top命令得到以下结果(P按照进程负载排序):
通过上图可以明显看出进程PID2221 明显存在问题,定位到了进程id。为了更好的排查问题,下面详细介绍top命令显示的含义。
1)第一行是任务队列信息
top - 14:06:34 up 537 days, 6 min, 6 users, load average: 0.41, 0.45, 0.43
任务队列信息 | 含义 |
---|---|
14:06:34 | 当前时间 |
537 days | 系统运行时间 |
6 min | 用户在线时间 |
6 users | 在线用户数 |
load average: 0.41, 0.45, 0.43 | 系统负载,即任务队列的平均长度。1分钟前、5分钟前、15分钟前平均负载 |
2) 第二行为进程的信息
进程信息 | 含义 |
---|---|
Tasks: 1 total | 进程总数 |
0 running | 正在运行的进程数 |
1 sleeping | 睡眠的进程数 |
0 stopped | 停止的进程数 |
0 zombie | 僵尸进程数 |
3)第三行为cpu信息
cpu信息 | 含义 |
---|---|
6.1% us | 用户空间占用CPU百分比 |
1.5% sy | 内核空间占用CPU百分比 |
0.0% ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
92.2% id | 空闲CPU百分比 |
0.0% wa | 等待输入输出的CPU时间百分比 |
0.0% hi | 硬件中断 |
0.0% si | 软件中断 |
0.0%st | 实时 |
4)第四、五行为内存信息,内容如下:
物理内存信息 | 含义 |
---|---|
Mem: 191272k total | 物理内存总量 |
173656k used | 使用的物理内存总量 |
17616k free | 空闲内存总量 |
22052k buffers | 用作内核缓存的内存量 |
交换区信息 | 含义 |
---|---|
Swap: 192772k total | 交换区总量 |
0k used | 使用的交换区总量 |
192772k free | 空闲交换区总量 |
123988k cached | 缓冲的交换区总量 |
二、通过top命令定位问题进程中每个线程占用cpu情况
top -Hp 2221
查看进程PID 2221的每一个线程占用CPU情况,如图。
由上图明显可以发现,线程PID2244CPU占用率最高,接下来定位该线程的代码是否出现异常导致cpu占用过高。
三、通过jstack 命令定位问题代码
上一步发现线程PID2244占用的CPU过高,就将这个PID转换成16进制
printf “%x\n” 线程PID
printf “%x\n” 2244
PID 2244转化成16进制为8c4。使用如下命令命令定位问题代码:
jstack pid |grep tid -A 30(pid:进程id,tid:线程id)
jstack 2221 | grep 8c4 -A 30
或者
jstack 2221| grep 8c4 -C5 --color
RUNNABLE 线程运行中或I/O等待
BLOCKED 线程在等待monitor锁(synchronized关键字)
TIMED_WAITING 线程在等待唤醒,但设置了时限
WAITING 线程在无限等待唤醒
线程在等待的状态。查看代码
public String testCode(){
test();
return "success";
}
public void test(){
while(true){
for(int i=0;i<10;i++){
}
}
}
while循环无法结束,一直抢占cpu,导致程序cpu使用过高,修改代码即可。