如何在 Windows 上获取未在控制台中运行的 Java 进程的线程和堆转储
我有一个从控制台运行的Java应用程序,它又执行另一个Java进程。我想获取该子进程的线程/堆转储。
在Unix上,我可以做一个,但在Windows AFAIK上,获得线程转储的唯一方法是控制台中的Ctrl-Break。但这只给了我父进程的转储,而不是子进程。kill -3 <pid>
有没有另一种方法可以获取该堆转储?
我有一个从控制台运行的Java应用程序,它又执行另一个Java进程。我想获取该子进程的线程/堆转储。
在Unix上,我可以做一个,但在Windows AFAIK上,获得线程转储的唯一方法是控制台中的Ctrl-Break。但这只给了我父进程的转储,而不是子进程。kill -3 <pid>
有没有另一种方法可以获取该堆转储?
您可以使用 来获取正在运行的任何进程的转储,前提是您知道 .jmap
pid
使用任务管理器或资源监视器获取 .然后pid
jmap -dump:format=b,file=heap.hprof <pid>
以获取该进程的堆。
对于安装了 和 且正在运行单个 Java 进程的系统,请尝试:bash
pgrep
jmap -dump:format=b,file=heap.hprof $(pgrep java)
你混淆了两个不同的java转储。 生成线程转储,而不是堆转储。kill -3
线程转储 = 将 JVM 输出中每个线程的跟踪作为文本堆叠到 stdout。
堆转储 = JVM 进程输出到二进制文件的内存内容。
要在Windows上进行线程转储,如果您的JVM是前台进程,则+是最简单的方法。如果你在Windows上有一个类似Unix的shell,比如Cygwin或MobaXterm,你可以像在Unix中一样使用。CTRLBREAKkill -3 {pid}
要在Unix中进行线程转储,如果您的JVM是前台进程,或者只要您为JVM获得正确的PID就可以工作。CTRLCkill -3 {pid}
无论使用哪种平台,Java都附带了几个可以提供帮助的实用程序。对于线程转储,这是您最好的选择。http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.htmljstack {pid}
只是为了完成转储问题:堆转储不常用,因为它们很难解释。但是,如果您知道在哪里/如何查看它们,它们会有很多有用的信息。最常见的用法是查找内存泄漏。最好在 java 命令行上设置 ,以便在 OutOfMemoryError 上自动生成堆转储,但是,您也可以手动触发堆转储。最常见的方法是使用java实用程序 。-D
-XX:+HeapDumpOnOutOfMemoryError
jmap
注意:此实用程序并非在所有平台上都可用。从JDK 1.6开始,可以在Windows上使用。jmap
示例命令行看起来像这样
jmap -dump:file=myheap.bin {pid of the JVM}
输出“myheap.bin”不是人类可读的(对于我们大多数人来说),你需要一个工具来分析它。我更喜欢MAT. http://www.eclipse.org/mat/