日期:2014-05-16  浏览次数:20621 次

linux下dump耗CPU的java线程

经常发现系统load值高,然后想去查找具体是哪个java线程导致的,一般会使用top ?jstack等等,但是每次都是人肉操作,故希望能将这个过程自动化,故这里写了个脚本用于dump出当前耗cpu的java线程堆栈。



分析下脚本处理过程:

1:利用top H列出当前线程的情况

2:grep出线程id

3:转换为jstack中的十六进制的线程id

4:利用jstack dump出线程

5:grep出所需要的线程上下文

?

?

直接上脚本代码

?

top -b -H -n 1 -p $1 | fgrep java -m $2 | awk '{print "obase=16;"$1}' | bc | awk '{printf"nid=0x%s|",$0}'| awk '{print substr($0,1,length()-1)}' > /tmp/nid.log 2>&1 &

/opt/sun/java/bin/jstack -l $1 > /tmp/js.log 2>&1 &

wait

cat /tmp/nid.log && cat /tmp/nid.log |xargs -i egrep {} /tmp/js.log -A 10 -i
?

本想借助管道一个命令完全实现的,发现grep如果接受2个动态参数行不通,故拆分开用2个进程来做的


说明下使用方式

sh ?topJava.sh ?pid ?threadNum


topJava.sh :是这个脚本的名字

pid :是要监控的java进程的id,其实如果只有一个java进程,那我可以用另外神奇的命令帮你获得,不过为了通用还是当成参数了。

threadNum :是要监控的java线程的个数,例如我想看最耗cpu的5个线程,则传递5

?

?

这里完全是用shell脚本来实现的,当然也可以完全用java的方式实现,不过java实现起来没这么简单要用MBean还有jvm tools相关的类,写一坨代码做shell的事情划不来。