我在标准的Windows命令窗口中有一个正在运行的java进程。即我已经运行'cmd'并输入java -jar ...
如果可能的话,我需要能够获得所有线程的完整堆栈转储。
我记得在linux下你可以通过quit命令上的一个选项向JVM发送一条消息。
在this document太阳州
在Windows上生成堆栈跟踪 95,或Windows NT平台,输入 关键序列 Java程序所在的窗口 运行,或单击关闭按钮 窗口。
这显然是错误的,因为关闭终端只会杀死进程并关闭窗口。
答案 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)
这可能对您有所帮助,但也取决于您使用的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
答案 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浏览器中的堆栈跟踪。