在Windows上的Java堆转储

我有一个标准的Windows命令窗口中运行的Java进程。 即我已经运行“cmd”,并在java -jar中键入…

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

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

在这个文件太阳状态

要在Windows 95或Windows NT平台上生成堆栈跟踪,请在正在运行Java程序的窗口中input密钥序列,或者单击窗口上的closuresbutton。

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

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

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

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

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

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

这给你一个线程转储。

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

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

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

其他的海报是正确的 – 在控制台或jstack ctrl中断。

否则,如果您使用的是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(); } 

然后,您可以选择任何想要陷入程序的方法来引起这种情况发生,并格式化/指导输出。

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

看看这个堆栈溢出帖子

线程转储编程/ JDI(Java调试器接口)

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