Windows上的Java堆栈转储

时间:2010-01-23 20:51:50

标签: java windows

我在标准的Windows命令窗口中有一个正在运行的java进程。即我已经运行'cmd'并输入java -jar ...

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

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

this document太阳州

  

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

这显然是错误的,因为关闭终端只会杀死进程并关闭窗口。

7 个答案:

答案 0 :(得分:36)

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

答案 1 :(得分:18)

键入 Ctrl + Break 是在Windows上生成线程转储的正确方法。

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

答案 2 :(得分:5)

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

连接时,右侧有一个Threads窗格,它有一个Thread Dump按钮。

这为您提供了一个线程转储。

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

Notes jvisualvm还允许您拍摄整个应用程序的快照以供以后分析。

答案 3 :(得分:1)

答案 4 :(得分:1)

除了Seth的回答,你还可以在你的机器上启动一个JConsole,以便检查每个线程的堆栈跟踪。这样做的另一个好处是能够检测死锁并监视内存使用情况。

答案 5 :(得分: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();
}

然后,您可以选择想要捕获程序的任何方法来实现此目的,并格式化/指导输出。

这种方法的缺点在于它并不精确,因为不能保证不同螺纹的堆叠在完全相同的时间进行。但是,相关的性能优势在于,在拍摄快照时不会暂停整个过程。

答案 6 :(得分:0)

看看这个Stack Overflow帖子

Thread dump programmatically /JDI (Java Debugger Interface)

我们已经实现了一个JMX方法来转储堆栈跟踪。这非常方便,因为您甚至可以在远程计算机上检查Web浏览器中的堆栈跟踪。