4.2.6 jstack:Java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。

jstack命令格式:


jstack[option]vmid


option选项的合法值与具体含义见表4-5。

figure_0129_0045

代码清单4-4是使用jstack查看Eclipse线程堆栈的例子,例子中的3500是通过jps命令查询到的LVMID。

代码清单4-4 使用jstack查看线程堆栈(部分结果)


C:\Users\IcyFenix>jstack-l 3500

2010-11-19 23:11:26

Full thread dump Java HotSpot(TM)64-Bit Server VM(17.1-b03 mixed mode):

"[ThreadPool Manager]-Idle Thread"daemon prio=6 tid=0x0000000039dd4000 nid=0xf50 in Object.wait()[0x000000003c96f000]

java.lang.Thread.State:WAITING(on object monitor)

at java.lang.Object.wait(Native Method)

-waiting on<0x0000000016bdcc60>(a org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor)

at java.lang.Object.wait(Object.java:485)

at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:106)

-locked<0x0000000016bdcc60>(a org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor)

Locked ownable synchronizers:

-None


在JDK 1.5中,java.lang.Thread类新增了一个getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。使用这个方法可以通过简单的几行代码就完成jstack的大部分功能,在实际项目中不妨调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈,如代码清单4-5所示,这是笔者的一个小经验。

代码清单4-5 查看线程状况的JSP页面


<%@page import="java.util.Map"%>

<html>

<head>

<title>服务器线程信息</title>

</head>

<body>

<pre>

<%

for(Map.Entry<Thread,StackTraceElement[]>stackTrace:Thread.

getAllStackTraces().entrySet()){

Thread thread=(Thread)stackTrace.getKey();

StackTraceElement[]stack=(StackTraceElement[])stackTrace.getValue();

if(thread.equals(Thread.currentThread())){

continue;

}

out.print("\n线程:"+thread.getName()+"\n");

for(StackTraceElement element:stack){

out.print("\t"+element+"\n");

}

}

%>

</pre>

</body>

</html>