通过Java thread dump分析找到耗费CPU最高的源代码

通过Java thread dump分析找到耗费CPU最高的源代码

作者:胡家辉 2010-04-11

最近产品在运行过程中出现了性能问题,在很低的流量的情况下CPU就达到40%,流量稍高时CPU就达到98%

产品是Java写的,运行于JBOSS平台。操作系统为redhat linux。当你通过top命令发现你的应用程序的进程占用CPU98%时,我想你肯定想知道究竟是哪个地方耗费了如此的CPU处理时间。通过thread dump分析就可以找到,但这只是解决问题的第一步,即找到问题的所在。

首先:如何产生thread dump日志?

第一步:找到应用程序所在的进程号,通过top命令可以找到,不详述。

第二步:执行kill -3 pid获取thread dump日志(pid就是第一步获取到的)。注意:在不同的linux环境下执行输出的日志的地方可能不同。在IBMPowerPC小型机上的linux上执行kill -3 pid会在工作目录下产生类似javacore.20100409.161739.7614.0001.txt的文件。而在我所在的环境中,thread dump信息输出到JBOSS的日志文件中的。

其次:获取线程信息

大多数服务器应用都是多线程,因此必须查到具体是哪些线程占用的CPU高。通过top –H命令可以查看到应用程序的线程信息及占用CPU的情况。

如下所示:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                             

 4280 nbg-syst  18   0 3608m 2.0g  21m R 93.6 25.9   5004:49 java                                                

 4279 nbg-syst  18   0 3608m 2.0g  21m R 92.6 25.9   4876:40 java                                                

 4281 nbg-syst  18   0 3608m 2.0g  21m R 92.6 25.9   3892:54 java                                                 

 4282 nbg-syst  18   0 3608m 2.0g  21m R 91.2 25.9   4954:40 java                                                

 4244 nbg-syst  15   0 3608m 2.0g  21m S  3.3 25.9 168:34.04 java                                                       

PID所在的列即是对应的线程ID,这是十进制的。

最后:找到耗费CPU高的线程及对应的源代码

取上面耗费CPU最高的第一行的PID 4280,将其转化为十六进制得到0x10b8。然后在thread dump日志中搜索0x10b8,将会搜到如下信息:

"Stack.ClientSelector-1" daemon prio=10 tid=0x000000004baeec00 nid=0x10b8 runnable [0x0000000053169000..0x0000000053169c90]

   java.lang.Thread.State: RUNNABLE

       at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)

       at sun.nio.ch.EPollArrayWrapper.poll(Unknown Source)

       at sun.nio.ch.EPollSelectorImpl.doSelect(Unknown Source)

       at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)

       - locked <0x00002aaac4105468> (a sun.nio.ch.Util$1)

       - locked <0x00002aaac4131670> (a java.util.Collections$UnmodifiableSet)

       - locked <0x00002aaac3f79c78> (a sun.nio.ch.EPollSelectorImpl)

       at sun.nio.ch.SelectorImpl.select(Unknown Source)

       at com.*****.warlock.protocolstack.impl.layer2.nio.ActiveSelectorImpl.callSelect(ActiveSelectorImpl.java:288)

       at com. *****.warlock.protocolstack.impl.layer2.nio.ActiveSelectorImpl.run(ActiveSelectorImpl.java:163)

上面日志中的nid即是线程号。这样可以清晰的看到耗费CPU的源代码的具体位置,可以精确到行号。

备注:上面有部分采用*****是为了屏蔽公司版权信息而设置的,不是*哈。以上举例都是基于HP Blade硬件,redhat企业版操作系统和SunJDK

 

结束语:thread dump的作用远不只一点,比如还可以从中发现很多应用程序运行问题,比如死锁等。对于该日志还有一个Eclipse插件的可视化分析工具lockness,我试了一下感觉不错。大家可以参考(3)。

 

下面是关于这个话题的很好的参考资料,一并列出供大家参考。

参考文献:

(1)       http://weblogic.sys-con.com/node/44027 Analyzing Java Application Problems--Using Java thread dumps to assess the problem

(2)       http://publib.boulder.ibm.com/infocenter/wasinfo/v4r0/index.jsp?topic=/com.ibm.support.was40.doc/html/100__CPU_Usage/swg21162381.html Determining which Java thread is consuming CPU cycles on Solaris systems

(3)       http://lockness.plugin.free.fr/home.php Lockness Eclipse Plugin for thread dump GUI analysis tool

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gobitan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值