Java性能分析 - 通过top、jmap、jstack,快速分析JVM线程

it2022-05-05  127

本文所述的方法操作简单,但要能快速定位问题,需要一些重复练习和实践。

排查线程死循环

思路

通过top -H -p $pid列出进程的所有线程,默认是按cpu排序的(可按<或>调整排序字段,我常用的还有TIME+);如果有死循环线程,在未休眠或挂起的情况下(占用一核),将会显示在最上方

找到线程,通过jstack $pid | grep $thread_id -a30定位到堆栈

注:jstack中记录的thread_id是16进制,top拿到的线程ID是10进制,grep时需自行转化

编写脚本

##! /bin/bash ##! 查看某Java线程栈 ##! @Ahthor: Will ## 声明提示配色 strong_tip="\033[44m\033[37m" warn_tip=$strong_tip"\033[05m" error_tip="\033[41m\033[37m" tip_ending="\033[0m" ## 获取输入参数 pid=$1 if [ "$pid" == "" ]; then echo -ne "$warn_tip Please input $tip_ending$strong_tip pid of java process: $tip_ending" read pid fi if [ "$pid" == "" ]; then echo -e "$error_tip Usage: Unknown pid of java process. $tip_ending" exit 2 fi echo "***********************************************************************************************************************" echo -e "\t[" $(date -d "today" +"%Y-%m-%d %H:%M:%S") "] $strong_tip show thread detail of the process " $pid "$tip_ending: " echo "***********************************************************************************************************************" top -Hn1 p $pid tid=$2 if [ "$tid" == "" ]; then echo -ne "$warn_tip Please input $tip_ending$strong_tip tid of java thread: $tip_ending" read tid fi if [ "$tid" == "" ]; then echo -e "$error_tip Usage: Unknown tid of java thread. $tip_ending" exit 2 fi tid_hex=`printf "%x" $tid` echo -e "\n*****************************************************************" echo -e "\t[" $(date -d "today" +"%Y-%m-%d %H:%M:%S") "] $strong_tip finding the stack of tid " $tid "(hex:" $tid_hex ") $tip_ending" echo -e "*****************************************************************" jstack $pid | grep $tid_hex -a30 &

排查线程挂起阻塞等异常情况

上面的脚本仅适合简单的、可快速通过cpu资源异常定位的情况。但一般业务中还有其他情况:

线程可能是间歇休眠的、难以捕捉线程阻塞、导致线程池占满CPU高的都是gc线程,看出gc很忙,但不知道哪个业务一直在频繁请求内存

针对上面的情况,第一种方法就不管用了。 我采用的方案是使用jstack导出完整的栈,然后重点排查BLOCKED的线程,也可以统计某一类线程的数量,看有否异常。

命令很简单:jstack -l ${pid} | tee -a $file 导出的文件内容如下图: 重点关注java.lan.Thread.State,等待、阻塞的线程,可以进一步通过waiting on后面的描述、tid进行追溯。

还有个小策略,对比先后导出的两个栈文件,看重复的有哪些内容,往往就是高频操作、或阻塞的逻辑。

囿于时间关系,没有整理案例,有问题可以留言交流。


最新回复(0)