读《JAVA并发编程的艺术》笔记---第二步,使用jstack查找分析程序运行时线程状态

第一篇了解到了关于多线程编程时会遇到的一些问题,今天就使用jstack了解分析一下程序运行时的线程状态和信息

首先,按照惯例什么是jstack

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

博主私底下做了多线程启动时的资源消耗测试,然后根据以上流程使用jstack定位到了确切的线程启动代码位置,以后如果大家在多线程环境开发时遇到了过度的资源消耗问题,不妨也用jstack分析一下到底是哪里出了问题呢...

下一篇--读《JAVA并发编程的艺术》笔记---第三步,volatile与synchronized利弊分析

上一篇--读《JAVA并发编程的艺术》笔记---第一步,分析多线程与单线程的区别,以及并发带来的问题和解决方法


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值