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

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

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


当前回答

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

jcmd PID GC.heap_dump /tmp/dump

其他回答

如果您使用的是JDK 1.6或以上版本,您可以使用jmap命令来获取Java进程的堆转储,条件是您应该知道ProcessID。

如果你在Windows机器上,你可以使用任务管理器来获取PID。对于Linux机器,您可以使用各种命令,如ps -A | grep java或netstat -tupln | grep java或top | grep java,这取决于您的应用程序。

然后可以使用类似jmap -dump:format=b,file=sample_heap_dump的命令。hprof 1234,其中1234是PID。

有多种工具可用于解释hprof文件。我将推荐使用简单的Oracle的visualvm工具。

你可以从Cygwin发送kill -3 <pid>。你必须使用Cygwin ps选项来查找windows进程,然后将信号发送到该进程。

您必须将输出从第二个java可执行文件重定向到某个文件。 然后,使用SendSignal向第二个进程发送“-3”。

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

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