jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
寻找进程
执行命令jps找出Java进程ID,服务器上的Java应用名称为:
[root@oms ~]# jps 29188 Jps 1381 WrapperSimpleApp 22343 Bootstrap
也可以使用ps命令找出对应进程的进程ID:
[root@oms ~]# ps -aux|grep tomcat root 22343 14.6 21.5 4001076 837176 ? Sl Mar04 286:30 /usr/lib/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/ logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Xdebug -Xrunjdwp:transport=dt_socket,address=60022,suspend=n,server=y -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/lcoal/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
寻找线程
得到进程ID为22343,第二步找出该进程内最耗费CPU的线程,可以使用:
#1 ps -Lfp pid #2 ps -mp pid -o THREAD, tid, time #3 top -Hp pid
用第三个,输出如下:
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
[root@oms ~]# printf "%x " 22414 578e
得到22414的十六进制值为578e。
JStack查看分析线程及代码
[root@oms ~]# jstack 22343|grep -A10 578e "QueryCdrDataManager" #70 daemon prio=5 os_prio=0 tid=0x00007ff068fc3000 nid=0x578e waiting on condition [0x00007ff051fe8000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at com.houjing.test.thread.DataManager.run(DataManager.java:134)
由此可知这个线程当前正在执行这段代码:com.houjing.test.thread.DataManager.run(DataManager.java:134)
另:对于windows的分析请转至网友的另一篇博客:windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码