我有一个标准的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还允许您拍摄整个应用程序的快照以便稍后分析。
这可能对您有所帮助,但也取决于您使用的是哪个JVM版本和提供程序。
http://java.sun.com/developer/technicalArticles/J2SE/monitoring/
http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html
http://java.sun.com/javase/6/docs/technotes/guides/visualvm/index.html
除了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浏览器中检查堆栈跟踪。