CPU占比较高,怎么定位到问题代码?

linux软件性能排查

1.java语言

通过监控系统观察到CPU占比高达400%,满负荷工作。4个CPU,每个CPU运行占比都到达100%了。于是就开始了我们的问题查找。

步骤一:通过top命令查找CPU占比较大的进程号,如图所示:
在这里插入图片描述
步骤二:top -H -p 5363 通过这个命令查看5363这个进程中的线程的cpu使用情况,如图所示:
在这里插入图片描述

第一列PID是线程号,10进制的,%CPU列是线程占用的CPU比例。

在计算机中,线程号是用十六进制表示,如果要查看线程号5484的调用链,需要把十进制的5484转为十六进制,可以执行这个命令:echo “obase=16;5484” | bc 执行完之后可以看到打印出 156C,表明5484这个十进制数对应的16进制是156C。如图所示:
在这里插入图片描述
注意:jstack是java的命令,只适用于java
接下来执行命令 jstack 5363 | grep -A 50 156C 就可以看到线程156C的此刻瞬间调用链。差不对类似下面的这个图吧(下面的图是线程号为0x32c9的瞬间调用链,找到nid=0x32c9,nid后面的值就是16进制的线程号)。
在这里插入图片描述
步骤三:执行这段命令 jstack 5363 | grep -A 50 async-task

就可以看到进程5363下所有的线程名字带有async-task的线程的调用链情况,类似下图这个样子吧(下图是进程24671的线程调用链情况,只是截了部分图)。
在这里插入图片描述
看到线程的调用链,进一步可以找到线程正在执行的问题代码、进而对问题代码进行更改。

2.c语言

1 先查看进程pid

ps aux | grep xxx

2 查看线程占用率情况
top -H -p pid
linux中的线程是一个轻量级进程,每个线程都有自己的pid。执行这个命令后可以看出占用率最高的线程的PID。
单看进程pid我们很难知道我们代码中的哪个线程出了问题,我们可以利用prctl(PR_SET_NAME, “xxx”)给线程起名。至此我们通过线程名,大概可以猜到问题出现在哪个线程了。
然而还不够。

3 分析出问题的接口
strace -f -p PID
或者pstack PID
PID为上面的命令查看到的占用CPU最高的线程的PID。
之后可以看出调用最频繁的接口。

举个例子吧。这是一段C代码

#include <pthread.h>
#include <stdio.h>
#include <sys/prctl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>

void *thread_hndl1(void *arg)
{
        prctl(PR_SET_NAME, "thread_1");
        printf("i am thread_1 tid=0x%lx, pid=%d\n", 
              pthread_self(), syscall(SYS_gettid));
        while(1)
        {
                usleep(10);
        }
}
void *thread_hndl2(void *arg)
{
        prctl(PR_SET_NAME, "thread_2");
        printf("i am thread_2 tid=0x%lx, pid=%d\n", 
                    pthread_self(), syscall(SYS_gettid));
        while(1)
        {
                sleep(1);
        }
}

int main()
{
        pthread_t pid1,pid2;
        pthread_create(&pid1, NULL, thread_hndl1, NULL);
        pthread_create(&pid2, NULL, thread_hndl2, NULL);
        pthread_join(pid1, NULL);
        pthread_join(pid2, NULL);
}

先编译上面代码。

gcc -g -o debug_thread_mode debug_thread_mode.c -lpthread

运行程序

./debug_thread_mode

新开一个窗口,先查看debug_thread_mode的进程PID

ps aux | grep debug_thread_mode

在这里插入图片描述
进程号是21308,接着执行

top -H -p 21308

在这里插入图片描述
PID为21309,名字为thread_1(上面用prctl设置的)的线程cpu占用率最高。
接着执行

watch -n 1 pstack 21309

输出
在这里插入图片描述
问题大概出在nanosleep()接口
进一步验证,执行如下命令

strace -f -p 21309

输出
在这里插入图片描述
验证我们的猜想。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值