小强哥博客

小强哥,小强哥博客,技术大咖

利用jdk自带jstack工具线程调优

jstack是jdk自带的很强大的线程分析工具,可以帮助我们排查程序运行时的线程状态、死锁状态,jdk中同时自带的工具还有jps,jinfo,Jstack,jstat,jmap,jhat等。这里我是整理一下jstack的使用,如何帮助我们排查线上线程问题。

命令格式,如下,

jstack [-l] pid

在dump文件里,值得关注的线程状态有:

  • 死锁,Deadlock(重点关注) 。
  • 执行中,Runnable。
  • 等待资源,Waiting on condition(重点关注)。
  • 等待获取监视器,Waiting on monitor entry(重点关注)。
  • 暂停,Suspended。
  • 对象等待中,Object.wait() 或 TIMED_WAITING。
  • 阻塞,Blocked(重点关注)。
  • 停止,Parked。

如下截取的一段dump日志,

"pool-2-thread-6" #18 prio=5 os_prio=0 tid=0x0000000059e81000 nid=0x6d70 waiting on condition [0x000000005ad2e000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000da400720> (a java.util.concurrent.SynchronousQueue$TransferStack)
	at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
	at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(Unknown Source)
	at java.util.concurrent.SynchronousQueue$TransferStack.transfer(Unknown Source)
	at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
	- None
[pool-2-thread-6],线程名称,可以在程序中自定义,否则就是默认的。
[prio],线程的优先级,数字从1到10,其中1为最低,10为最高优先级。
[tid],线程id,由Thread.getId调用返回的一个独特的号码。
[nid],本地硬件线程id,这映射到一个依赖于平台的线程ID。等待监视锁实体[0x000000005ad2e000]
[waiting on condition],当前线程状态,表示等待唤醒。
[TIMED_WAITING],表示当前线程在等待一定时间后自动执行,这种情况一般是程序中使用了sleep等技术。

了解跟多可以参考:

http://www.cnblogs.com/zhengyun_ustc/archive/2013/03/18/tda.html

http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html