日期:2014-05-16 浏览次数:20675 次
经常发现系统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的事情划不来。