我有一个从控制台运行的Java应用程序,该应用程序反过来执行另一个Java进程。我想获得该子进程的线程/堆转储。

在Unix上,我可以执行kill -3 <pid>,但在Windows AFAIK上,获得线程转储的唯一方法是在控制台中按Ctrl-Break。但这只给了我父进程的转储,而不是子进程的转储。

有其他方法来获取堆转储吗?


当前回答

在Oracle JDK中,我们有一个名为jmap的命令(在Java Home的bin文件夹中可用)。 该命令的用法如下

Jmap (option) (pid)

示例:jmap -dump:live,format=b,file=heap.bin (pid)

其他回答

您可以运行jconsole(包含在Java 6的SDK中),然后连接到Java应用程序。它将显示每个正在运行的线程及其堆栈跟踪。

我推荐JDK附带的Java VisualVM (jvisualvm.exe)。它可以动态连接并访问线程和堆。我发现在某些问题上它是无价的。

如果你在服务器-jre 8及以上,你可以使用这个:

jcmd PID GC.heap_dump /tmp/dump

也许jcmd ?

Jcmd实用程序用于向JVM发送诊断命令请求,这些请求对于控制Java Flight records、故障排除以及诊断JVM和Java应用程序非常有用。

The jcmd tool was introduced with Oracle's Java 7 and is particularly useful in troubleshooting issues with JVM applications by using it to identify Java processes' IDs (akin to jps), acquiring heap dumps (akin to jmap), acquiring thread dumps (akin to jstack), viewing virtual machine characteristics such as system properties and command-line flags (akin to jinfo), and acquiring garbage collection statistics (akin to jstat). The jcmd tool has been called "a swiss-army knife for investigating and resolving issues with your JVM application" and a "hidden gem."

下面是调用jcmd时需要使用的过程:

进入jcmd <pid> GC。heap_dump <文件路径> 在这 pid: Java进程Id,将为其捕获堆转储 file-path:打印堆转储的文件路径。

有关获取Java堆转储的更多信息,请参阅本文。

您混淆了两个不同的java转储。Kill -3生成线程转储,而不是堆转储。

线程转储= JVM输出到stdout的每个线程的堆栈跟踪作为文本。 堆转储= JVM进程输出到二进制文件的内存内容。

要在Windows上进行线程转储,如果您的JVM是前台进程,CTRL+BREAK是最简单的方法。如果你在Windows上有一个类似Unix的shell,比如Cygwin或MobaXterm,你可以像在Unix中一样使用kill -3 {pid}。

要在Unix中进行线程转储,如果您的JVM是前台进程,则可以使用CTRL+C或kill -3 {pid},只要您为JVM获得正确的pid即可。

对于这两种平台,Java都提供了一些有用的实用程序。对于线程转储,jstack {pid}是最好的选择。http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.html

Just to finish the dump question out: Heap dumps are not commonly used because they are difficult to interpret. But, they have a lot of useful information in them if you know where/how to look at them. The most common usage is to locate memory leaks. It is a good practice to set the -D on the java command-line so that the heap dump is generated automatically upon an OutOfMemoryError, -XX:+HeapDumpOnOutOfMemoryError But, you can manually trigger a heap dump, also. The most common way is to use the java utility jmap.

注意:此实用程序并非在所有平台上都可用。从JDK 1.6开始,jmap可以在Windows上使用。

命令行示例如下所示

jmap -dump:file=myheap.bin {pid of the JVM}

输出“myheap.bin”不是人类可读的(对我们大多数人来说),您需要一个工具来分析它。我的首选是MAT. http://www.eclipse.org/mat/