windows上的java堆栈转储

windows上的java堆栈转储,java,windows,Java,Windows,我有一个在标准windows命令窗口中运行的java进程。ie我已经运行了“cmd”并输入了java-jar 如果可能的话,我需要能够获得所有线程的完整堆栈转储 我记得在linux下,您可以通过quit命令上的一个选项向JVM发送消息 处于阳光状态 在Windows上生成堆栈跟踪的步骤 95或Windows NT平台,输入 中的键序列 Java程序所在的窗口 正在运行,或单击屏幕上的关闭按钮 窗户 这显然是错误的,因为关闭终端只会终止进程并关闭窗口。键入Ctrl+Break是在Windows上生

我有一个在标准windows命令窗口中运行的java进程。ie我已经运行了“cmd”并输入了java-jar

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

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

处于阳光状态

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

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

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


你可能在按Ctrl+C(=中断)键吗?这将发送一个SIGINT,它通常会终止您的进程

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

这可能对您有所帮助,但也取决于您使用的JVM版本和提供程序


除了Seth的答案之外,您还可以在机器上启动JConsole,以检查每个线程的堆栈跟踪。这还有另外一个好处,即能够检测死锁并监视内存使用情况。

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

否则,如果您使用的是Java 1.5或更高版本,则可以通过以下方式在运行时以编程方式获取此信息:

Thread.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();
}
Map traces=Thread.getAllStackTraces();
迭代器i=traces.keySet().Iterator();
while(i.hasNext()){
螺纹thd=i.next();
System.out.println(“***线程id”+thd.getId()+”:“+thd.getName()+”***”);
StackTraceElement[]trace=traces.get(thd);
对于(int j=0;j
然后,您可以选择任何方法来捕获程序,以使其发生,并格式化/指导输出


这种方法的一个缺点是不精确,因为不同线程的堆栈不能保证在完全相同的时间获取。但是,还有一个相关的性能优势,即在拍摄快照时不会挂起整个进程。

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

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

这将为您提供一个线程转储

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


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

请看这篇堆栈溢出文章


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

如果您没有java进程的控制台窗口,那么这可以在Windows上获得线程转储。答案是完美的!