找出耗CPU的java线程脚本-优化版

来源:互联网 发布:如何部署apache服务 编辑:程序博客网 时间:2024/05/10 09:51

查找java进程中耗CPU的线程,分为以下三步:

1.列出进程id对应的线程id
ps -mp {pid} -o THREAD,tid,time

2.cpu占用高的线程id找出并转换为16进制
printf “%x\n” {tid}

3.打印出有问题的线程
jstack {pid} |grep {tid} -A 30

这样的方式有个问题,每次查问题需要多次输入,且每次只能找到一个线程栈信息,效率比较低。因此就有人将其制作成脚本,方便线上更快速的定位问题。以下是根据高人脚本稍微调整后的脚本,线上使用效果还不错,这里做个记录:

###### begin pid为86295的java进程中cpu>0的线程的堆栈######
pid=86295
sfile="/tmp/java.$pid.trace"
tfile="/tmp/java.$pid.trace.tmp"
rm -f $sfile  $tfile
echo "pid $pid"

jstack $pid > $tfile
ps -mp $pid -o THREAD,tid,time|awk '{if ($2>0 && $8 != "-") print $8,$2}'|while read line;
do
        nid=$(echo "$line"|awk '{printf("0x%x",$1)}')
        cpu=$(echo "$line"|awk '{print $2}')
        echo "nid: $nid, cpu: $cpu %">>$sfile
        lines=`grep $nid -A 100 $tfile |grep -n '^$'|head -1|awk -F':' '{print $1}'`
        ((lines=$lines-1))
        if [ "$lines" = "-1" ];
        then
             grep $nid -A 100 $tfile  >>$sfile
             echo '' >>$sfile
        else
             grep $nid -A $lines $tfile  >>$sfile
        fi
done
rm -f $tfile
echo "read msg in $sfile"
###########  end  ############

需要注意的是pid的获取依然需要多ps查找一次,建议pid的获取方式可以改为:

ps -ef|grep 你程序的关键字|grep -v 'grep'|awk '{print $2}'