获取 CPU 使用率最高的 Java 线程

  • lovebing 
  • 未分类

最近发现一个服务 JVM CPU 使用率居高不下,想了分析一下原因,于是写了一个 Shell 脚本,用来获取 CPU 使用率最高的Java 线程,然后再使用 jstack 分析。

首先使用 top 查看线程,由于 top 的输入带有控制台的显示格式,对字符串处理有一定的影响,所以需要删掉。使用 hexdump 观察不同字符串长度的格式,发现是有些区别的,所以使用 sed 进行多次替换。

由于服务部署在 k8s 上,Java 进程的 id 是 1,不需要做额外的判断。

#!/usr/bin/env bash
# Author: lovebing
# Date: 2019-09-30
lines=$(top -n 1 -Hp 1 | grep java | head -1 | sed 's/\x1b\x28\x42\x1b\[m//' | sed 's/\x1b\[1m//' | sed s/[[:space:]]/\ /g)
echo -e $lines
tid=$(echo $lines | awk '{print $1}')
tid_hex=$(printf "%x" ${tid})
cpu=$(echo $lines | awk '{print $9}')
mem=$(echo $lines | awk '{print $10}')
echo "tid: ${tid}"
echo "tid_hex: ${tid_hex}"
echo "cpu: ${cpu}%"
echo "mem: ${mem}%"

这是一个非常原始的版本,因为获得 tid 后,还需使用 jstack 打印线程信息,再从中找到相应的线程,比较麻烦,应该把这部分的逻辑也写到 script 里。

jstack 打印的信息,因为需要查找,得先保存到文件里,不然存在变量里会丢失文本格式。

所有最终的版本是:

#!/usr/bin/env bash
# Author: lovebing
# Date: 2019-09-30, 2019-10-16
pid=1
home=~/

lines=$(top -n 1 -Hp ${pid} | grep java | head -1 | sed 's/\x1b\x28\x42\x1b\[m//' | sed 's/\x1b\[1m//' | sed s/[[:space:]]/\ /g)
echo -e $lines
tid=$(echo $lines | awk '{print $1}')
tid_hex=0x$(printf "%x" ${tid})
cpu=$(echo $lines | awk '{print $9}')
mem=$(echo $lines | awk '{print $10}')

if test -z ${tid}
then
        echo 'not found'
        exit
fi
echo "tid: ${tid}"
echo "tid_hex: ${tid_hex}"
echo "cpu: ${cpu}%"
echo "mem: ${mem}%"

jstack_content_file="${home}/jstack_content_"$(date '+%Y%m%d%H%M%S')

jstack ${pid} > ${jstack_content_file}


start_index=$(grep -n "nid=${tid_hex} " ${jstack_content_file} | awk -F ':' '{print $1}')

if test -z ${start_index}
then
        echo 'not found'
        rm ${jstack_content_file}
        exit
fi

let from_index=start_index+1 
let to_index=start_index+100

end_index=$(sed -n "${from_index}, ${to_index}p" ${jstack_content_file} | grep -n 'nid=0x' | head -1 | awk -F ':' '{print $1}')

if test -z ${end_index}
then
        tail -${start_index} ${jstack_content_file} 
else
        let end_index=start_index+end_index-1
        sed -n "${start_index},${end_index}p" ${jstack_content_file} 
fi

rm ${jstack_content_file}

发表评论

电子邮件地址不会被公开。 必填项已用*标注