方法一:
1.jps 获取Java进程的PID。
2.jstack pid >> java.txt 导出CPU占用高进程的线程栈。
3.top -H -p PID 查看对应进程的哪个线程占用CPU过高。
4.echo “obase=16; PID” | bc 将线程的PID转换为16进制,大写转换为小写。
5.在第二步导出的Java.txt中查找转换成为16进制的线程PID。找到对应的线程栈。
6.分析负载高的线程栈都是什么业务操作。优化程序并处理问题。
一键脚本如下:
#!/bin/bash
# 进程ID
PID=$1
top -n 1 -H -p ${PID}
echo ""
for param in $(top -n 1 -H -p ${PID} | awk '{print $1,$10}' | grep -o -E '[0-9]+ .+' | head -n 20);do
echo ${param} | grep -o -E '^[0-9]+$*' >/dev/null 2>&1
if [[ $? -eq 0 ]];then
tid=${param}
echo "tid: ${tid}"
TID16=$(printf "%x\n" ${tid})
jstack ${PID} | grep -A 30 "nid=0x${TID16}"
else
cpu=${param}
echo "cpu: ${cpu}"
echo ""
echo""
fi
done
方法二:
1.使用top 定位到占用CPU高的进程PID
top
通过ps aux | grep PID命令
2.获取线程信息,并找到占用CPU高的线程
ps -mp pid -o THREAD,tid,time | sort -rn
3.将需要的线程ID转换为16进制格式
printf “%x\n” tid
4.打印线程的堆栈信息
jstack pid |grep tid -A 30
一键脚本如下:
#!/bin/bash
# 进程ID
PID=$1
ps -mp ${PID} -o THREAD,tid,time | sort -rn | head -n 20
echo ""
CPU_TOTAL=0
for param in $(ps -mp ${PID} -o THREAD,tid,time | sort -rn | head -n 20 | awk '{print $8,$2}' | grep -o -E '[0-9]+ .+' | head -n 20);do
echo ${param} | grep -o -E '^[0-9]+$*' >/dev/null 2>&1
if [[ $? -eq 0 ]];then
tid=${param}
echo "tid: ${tid}"
TID16=$(printf "%x\n" ${tid})
jstack ${PID} | grep -A 30 "nid=0x${TID16}"
else
cpu=${param}
echo "cpu: ${cpu}"
CPU_TOTAL=$(echo "${CPU_TOTAL} + ${cpu}" | bc)
echo ""
echo ""
fi
done
echo "cpu total: ${CPU_TOTAL}"