我有一个从控制台运行的Java应用程序,该应用程序反过来执行另一个Java进程。我想获得该子进程的线程/堆转储。
在Unix上,我可以执行kill -3 <pid>,但在Windows AFAIK上,获得线程转储的唯一方法是在控制台中按Ctrl-Break。但这只给了我父进程的转储,而不是子进程的转储。
有其他方法来获取堆转储吗?
我有一个从控制台运行的Java应用程序,该应用程序反过来执行另一个Java进程。我想获得该子进程的线程/堆转储。
在Unix上,我可以执行kill -3 <pid>,但在Windows AFAIK上,获得线程转储的唯一方法是在控制台中按Ctrl-Break。但这只给了我父进程的转储,而不是子进程的转储。
有其他方法来获取堆转储吗?
当前回答
您可以使用jmap获取正在运行的任何进程的转储,假设您知道pid。
使用任务管理器或资源监视器获取pid。然后
jmap -dump:format=b,file=heap.hprof <pid>
获取该进程的堆。
对于安装了bash和pgrep并且正在运行单个Java进程的系统,请尝试:
jmap -dump:format=b,file=heap.hprof $(pgrep java)
其他回答
您可以运行jconsole(包含在Java 6的SDK中),然后连接到Java应用程序。它将显示每个正在运行的线程及其堆栈跟踪。
Visualvm跟踪:
如果你不能从jvisualvm连接到你正在运行的JVM,因为你没有使用正确的JVM参数启动它(并且它在远程框上),在远程框上运行jstatd,然后,假设你有一个直接连接,在visualvm中将它添加为“远程主机”,双击主机名,该框上的所有其他JVM将神奇地显示在visualvm中。
如果你没有“直接连接”到那个盒子上的端口,你也可以通过代理来做到这一点。
一旦你可以看到你想要的进程,在jvisualvm中钻到它,并使用monitor选项卡-> "heapdump"按钮。
你可以从Cygwin发送kill -3 <pid>。你必须使用Cygwin ps选项来查找windows进程,然后将信号发送到该进程。
也许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堆转储的更多信息,请参阅本文。
如果你想在内存不足时进行堆转储,你可以使用-XX:-HeapDumpOnOutOfMemoryError选项启动Java
c.f. JVM选项参考页