第一篇了解到了关于多线程编程时会遇到的一些问题,今天就使用jstack了解分析一下程序运行时的线程状态和信息首先,按照惯例什么是jstackjstack是jvm自带的堆栈跟踪分析包,提供了生成程序运行时线程快照服务,用以定位线程等待,死锁等异常产生的原因.接下来就用jstack分析一下一个项目在运行时的线程运行使用情况,系统:linux,环境:jdk 1.7 tomcat 8先使用ps -ef |grep java 查找当前在运行的java进程

root     20146     1  6 Nov30 ?        07:33:01 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat_merchant/
	conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySi
	ze=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/local/tomcat_merchant/bin/boots
	trap.jar:/usr/local/tomcat_merchant/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat_merchant -Dcatalina.home=/usr/lo
	cal/tomcat_merchant -Djava.io.tmpdir=/usr/local/tomcat_merchant/temp org.apache.catalina.startup.Bootstrap start

得到pid为20146的java进程,然后使用top -p 20146 -H 查看所属子PID运行情况,得到以下片段

29303 root      20   0 11.7g 2.4g  13m S 20.6  7.7   0:19.36 java               
29276 root      20   0 11.7g 2.4g  13m S  0.0  7.7   0:00.00 java               
29277 root      20   0 11.7g 2.4g  13m S  0.0  7.7   0:00.56 java               
29278 root      20   0 11.7g 2.4g  13m S  0.0  7.7   0:00.19 java

可见pid为29303所占的实时资源最多,那我们就用jstack来分析一下是哪些程序占用了这部分资源.先把29303转16进制,得到7277

下一步终于轮到jstack上场了,使用jstack  pid 命令 可以打印出实时线程快照,如果信息过长,可以使用jstack pid > filename.txt 将快照日志输出到文件中,

附一段博主的关于以上7277的快照片段

"ContainerBackgroundProcessor[StandardEngine[Catalina]]" #21 daemon prio=5 os_prio=0 tid=0x00007f5444366000 nid=0x7277 waiting on condition [0x00007f542647e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1340)
	at java.lang.Thread.run(Thread.java:748)

可以看到nid为0x7277,其中0x代表是16进制的7277,对应以上10进制pid29303,根据提示,该线程处于TIMED_WAITING状态,而ContainerBase.java为tomcat内置的日志输入输出对象,再实时.观察一下Catalina.out的输出信息发现,当CPU被占用时,就是tomcat在写入Catalina.out日志信息时,因为项目中有详细的日志输出记录,所以博主不希望这部分资源被tomcat吃掉,关掉了tomcat的日志输入再查看资源消耗,发现没有了该部分的资源消耗.

同理,如果是多线程的因素导致了CPU资源过度消耗,那么就针对业务尽可能的减少线程数量,以及锁开销,或者使用其他合理方式解决(具体,以后再写)就降低了频繁的上下文切换,节省了多线程切换和资源竞争产生的开销,那么就'大大'的提升程序性能了.