* 结束:terminated
线程的不同状态暗示系统的性能是不一样的,这个时候需要监控线程状态,用java自带的性能监控工具jstack。
==================================================================
jstack可以打印出给定的Java进程的Java堆栈信息
命令格式:# jstack [ option ] pid
======================================================================================
第一步定位出正在执行的jAVA进程号 :
这里我上传到Linux服务器的应用名是“thread-test”
使用命令:# ps -ef | grep thread-test.jar | grep -v grep
查询结果:root 3407 2338 26 20:33 pts/0 00:08:55 java -jar thread-test.jar 1 进程号为3407
或者使用命令:#ps -ef|grep java
查询结果:root 2630 1 0 19:16 pts/0 00:00:20 /usr/java/jdk1.6.0_10/bin/java -Djava.util.logging.config.file=/export/servers/tomcat-server-1/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/export/servers/tomcat-server-1/endorsed -classpath /export/servers/tomcat-server-1/bin/bootstrap.jar:/export/servers/tomcat-server-1/bin/tomcat-juli.jar -Dcatalina.base=/export/servers/tomcat-server-1 -Dcatalina.home=/export/servers/tomcat-server-1 -Djava.io.tmpdir=/export/servers/tomcat-server-1/temp org.apache.catalina.startup.Bootstrap start
root 3407 2338 26 20:33 pts/0 00:08:00 java -jar thread-test.jar 1
root 3636 3417 0 21:03 pts/1 00:00:00 grep java
也可以查询到thread-test.jar的进程号也是3407
=====================================================================
第二步 使用命令:#jstack 3407
thread-test.jar应用的堆栈信息:"TestXXX..." (线程名)prio=10 tid=0xb7553000 nid=0xd58 runnable [0xb4d24000..0xb4d250f0]
java.lang.Thread.State: RUNNABLE(业务线程是运行状态)
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:260)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
- locked <0x8bd77898> (a java.io.BufferedOutputStream)
at java.io.PrintStream.write(PrintStream.java:432)
- locked <0x8bd74cd0> (a java.io.PrintStream)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
- locked <0x8bd74c90> (a java.io.OutputStreamWriter)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
at java.io.PrintStream.newLine(PrintStream.java:496)
- locked <0x8bd74cd0> (a java.io.PrintStream)
at java.io.PrintStream.println(PrintStream.java:757)
- locked <0x8bd74cd0> (a java.io.PrintStream)
at com.lee.thread.ThreadStatusTest.runnable(ThreadStatusTest.java:42)
at com.lee.thread.BlockedStatus.run(ThreadStatusTest.java:87)(正在运行run方法的87行,可以去查看对应的代码信息)
at java.lang.Thread.run(Thread.java:619)
从下往上看堆栈信息
再比如:
"TestXXX..." prio=10 tid=0xb7653000 nid=0xf3a waiting for monitor entry [0xb4d24000..0xb4d24df0]
java.lang.Thread.State: BLOCKED (on object monitor)(业务运行死锁状态)
at java.io.PrintStream.println(PrintStream.java:755)
- waiting to lock <0x8bd70fc0> (a java.io.PrintStream)
at com.lee.thread.ThreadStatusTest.blocked(ThreadStatusTest.java:71)
- locked <0x8bd70fa0> (a java.lang.String)
at com.lee.thread.BlockedStatus.run(ThreadStatusTest.java:90)
at java.lang.Thread.run(Thread.java:619)
以上堆栈信息可以抓取到这两行有用信息:
at com.lee.thread.ThreadStatusTest.blocked(ThreadStatusTest.java:71)
at com.lee.thread.BlockedStatus.run(ThreadStatusTest.java:90)
在相应类的方法的71行和90行代码都有问题,进入代码行排查。
======================================================================
另外,如果堆栈信息太多,可以打印到文件里
使用命令:[root@zhoucentos ~]# jstack 3889 > a.txt
a.txt文件保存就在当前目录下:
[root@zhoucentos ~]# ll
总用量 12084
-rwx--x--x. 1 root root 1751 10月 1 2015 anaconda-ks.cfg
-rw-r--r--. 1 root root 3467 12月 20 21:55 a.txt
这样就可以将a.txt下载到Windows本地查看。
======================================================================