2010-01-23 152 views
22

我在标准的Windows命令窗口中运行java进程。即我已经运行'cmd'并输入java -jar ...窗口上的java堆栈转储

我需要能够得到所有线程的完整堆栈转储,如果可能的话。

我记得在linux下你可以通过quit命令中的一个选项向JVM发送消息。

this document太阳状态

要生成在Windows 95或Windows NT平台的堆栈跟踪,在 窗口,Java程序是 运行进入 键序列,或单击关闭窗口上的按钮 。

这显然是错误的,因为关闭终端除了杀死进程并关闭窗口外什么也不做。

回答

18

打字按Ctrl +休息产生在Windows线程转储的正确方法。

您是否按Ctrl + C(=中断)也许?这将发送一个SIGINT,通常会杀死你的进程。

35

你可以使用jstack [ option ] pid(如果问题是关于线程转储)。使用jps来查找Java进程的标识。

+0

如果您没有java进程的控制台窗口,那么这适用于在Windows上获取线程转储。 – ssasa 2012-10-17 10:20:13

1

除了Seth的回答,你也可以为了检查每个线程的堆栈跟踪启动JConsole的你的机器上。这具有能够检测死锁和监视内存使用情况的额外好处。

1

其他海报是正确的 - 控制台或jstack中的ctrl-break。

否则,如果您使用的是Java 1.5或以上,就可以得到该信息编程在运行时保持,通过:

Thread.getAllStackTraces()http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#getAllStackTraces()

然后遍历这些结果。

有点啰嗦,但这样的事情:

Map<Thread,StackTraceElement[]> traces = Thread.getAllStackTraces(); 
Iterator<Thread> i = traces.keySet().iterator(); 
while (i.hasNext()) { 
    Thread thd = i.next(); 
    System.out.println("*** Thread id"+thd.getId()+":"+thd.getName()+" ***"); 
    StackTraceElement[] trace = traces.get(thd); 
    for (int j=0; j < trace.length; ++j) { 
     System.out.println(trace[j]); 
    } 
    System.out.println(); 
} 

然后你可以选择你想要困住你的程序导致这种情况发生任何方法和格式/直接输出。

这种方法的一个缺点是它不是确切的,因为不能确保在不同线程的堆栈完全同时被采用。但是,有一个相关的性能优势,即在拍摄快照时不会暂停整个过程。

5

在Java 6 JDK +中,jvisualvm可执行文件允许您附加到正在运行的程序(双击其左侧的条目)。

连接后,右侧有一个线程窗格,其中有一个线程转储按钮。

这给你一个线程转储。

一旦生成,您可以A)全选 - 将线程转储复制并粘贴到文本编辑器。或B)您可以右键单击左侧树中创建的线程转储,并说“另存为”。

备注jvisualvm还允许您拍摄整个应用程序的快照,以便稍后进行分析。