如何在 Windows 上获取未在控制台中运行的 Java 进程的线程和堆转储
我有一个从控制台运行的 Java 应用程序,该应用程序又执行另一个 Java 进程。 我想获取该子进程的线程/堆转储。
在 Unix 上,我可以执行 kill -3
但在 Windows 上,据我所知,获取线程转储的唯一方法是在控制台中按 Ctrl-Break。 但这只给了我父进程的转储,而不是子进程的转储。
还有其他方法来获取堆转储吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
假设您知道
pid
,您可以使用jmap
获取任何正在运行的进程的转储。使用任务管理器或资源监视器获取
pid
。 然后获取该进程的堆。
对于安装了 bash 和 pgrep 且正在运行单个 Java 进程的系统,请尝试:
You can use
jmap
to get a dump of any process running, assuming you know thepid
.Use Task Manager or Resource Monitor to get the
pid
. Thento get the heap for that process.
For systems where
bash
andpgrep
are installed and a single Java process is running, try:您混淆了两个不同的 java 转储。
kill -3
生成线程转储,而不是堆转储。要在 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只是为了解决转储问题:堆转储并不常用,因为它们很难解释。 但是,如果您知道在哪里/如何查看它们,它们里面有很多有用的信息。 最常见的用途是定位内存泄漏。 最好在 java 命令行上设置
-D
,以便在发生 OutOfMemoryError 时自动生成堆转储,-XX:+HeapDumpOnOutOfMemoryError
但是,您也可以手动触发堆转储。 最常见的方法是使用 java 实用程序jmap
。注意:此实用程序并非在所有平台上都可用。 从 JDK 1.6 开始,
jmap
可在 Windows 上使用。示例命令行看起来像
输出“myheap.bin”不是人类可读的(对于我们大多数人来说),您将需要一个工具来分析它。 我的偏好是 MAT。 http://www.eclipse.org/mat/
You are confusing two different java dumps.
kill -3
generates a thread dump, not a heap dump.To take a thread dump on Windows, CTRL+BREAK if your JVM is the foreground process is the simplest way. If you have a unix-like shell on Windows like Cygwin or MobaXterm, you can use
kill -3 {pid}
like you can in Unix.To take a thread dump in Unix, CTRL+C if your JVM is the foreground process or
kill -3 {pid}
will work as long as you get the right PID for the JVM.With either platform, Java comes with several utilities that can help. For thread dumps,
jstack {pid}
is your best bet. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.htmlJust 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 utilityjmap
.NOTE: this utility is not available on all platforms. As of JDK 1.6,
jmap
is available on Windows.An example command-line would look something like
The output "myheap.bin" is not human readable (for most of us), and you will need a tool to analyze it. My preference is MAT. http://www.eclipse.org/mat/
我认为在 Linux 进程中创建 .hprof 文件的最佳方法是使用 jmap 命令。 例如:
jmap -dump:format=b,file=filename.hprof {PID}
I think the best way to create .hprof file in Linux process is with jmap command. For example:
jmap -dump:format=b,file=filename.hprof {PID}
除了使用提到的 jconsole/visualvm 之外,您还可以在另一个命令行窗口上使用 jstack -l <vm-id> 并捕获该输出。
jps
找到。jstack
和jps
都包含在 Sun JDK 版本 6 及更高版本中。In addition to using the mentioned jconsole/visualvm, you can use
jstack -l <vm-id>
on another command line window, and capture that output.The <vm-id> can be found using the task manager (it is the process id on windows and unix), or using
jps
.Both
jstack
andjps
are include in the Sun JDK version 6 and higher.我推荐随 JDK 一起发布的 Java VisualVM (jvisualvm.exe)。 它可以动态连接并访问线程和堆。 我发现它对于某些问题来说是无价的。
I recommend the Java VisualVM distributed with the JDK (jvisualvm.exe). It can connect dynamically and access the threads and heap. I have found in invaluable for some problems.
如果您使用的是 server-jre 8 及更高版本,您可以使用以下命令:
If you are on server-jre 8 and above you can use this:
如果您想要内存不足时的堆转储,可以使用选项
-XX:-HeapDumpOnOutOfMemoryError
cf JVM 选项参考页面
If you want a heapdump on out-of-memory, you can start Java with the option
-XX:-HeapDumpOnOutOfMemoryError
c.f. JVM Options reference page
尝试以下选项之一。
对于 32 位 JVM:
对于 64 位 JVM(显式引用):
对于 VM 参数中具有 G1GC 算法的 64 位 JVM(仅使用 G1GC 算法生成活动对象堆):
相关 SE 问题:jmap 命令的 Java 堆转储错误:过早 EOF
查看
jmap
的各种选项在这篇文章Try one of below options.
For 32 bit JVM:
For 64 bit JVM (explicitly quoting):
For 64 bit JVM with G1GC algorithm in VM parameters (Only live objects heap is generated with G1GC algorithm):
Related SE question: Java heap dump error with jmap command : Premature EOF
Have a look at various options of
jmap
at this article您可以从 Cygwin 发送
kill -3
。 您必须使用 Cygwin ps 选项来查找 Windows 进程,然后将信号发送到该进程。You can send the
kill -3 <pid>
from Cygwin. You have to use the Cygwinps
options to find windows processes then just send the signal to that process.您可以运行
jconsole
(包含在 Java 6 的 SDK 中),然后连接到您的 Java 应用程序。 它将向您显示每个正在运行的线程及其堆栈跟踪。You could run
jconsole
(included with Java 6's SDK) then connect to your Java application. It will show you every Thread running and its stack trace.您必须将第二个 java 可执行文件的输出重定向到某个文件。
然后,使用 SendSignal 到 发送“-3”到您的第二个进程。
You have to redirect output from second java executable to some file.
Then, use SendSignal to send "-3" to your second process.
如何获取java应用程序的进程id?
执行命令'jcmd'来获取java应用程序的进程id。
如何获取线程转储?
jcmd PID Thread.print > thread.dump
参考 链接
你甚至可以使用jstack来获取线程转储(jstack PID > thread.dump)。 参考链接
如何获取堆转储?
使用jmap工具获取堆转储。
jmap -F -dump:live,format=b,file=heap.bin PID
PID 代表应用程序的进程 ID。 参考链接
How to get process id of java application?
Execute the command 'jcmd' to get the process id of java applications.
How to get Thread dump?
jcmd PID Thread.print > thread.dump
Reference link
You can even use jstack to get thread dump (jstack PID > thread.dump). Reference link
How to get heap dump?
Use jmap tool to get heap dump.
jmap -F -dump:live,format=b,file=heap.bin PID
PID stands for process id of the application. Reference link
以下脚本使用 PsExec 连接到另一个 Windows 会话,因此即使通过远程桌面服务连接也能正常工作。
我为 Java 8 编写了一个小批处理脚本(使用
PsExec
和jcmd
) 名为jvmdump.bat
,它转储线程、堆、系统属性和 JVM 参数。
它必须在启动 JVM 的用户的同一 Windows 会话中运行,因此,如果您通过远程桌面连接,则可能需要在
Session 0
中启动命令提示符并从那里运行它。 例如,这将提示您(单击底部的任务栏图标)在交互式会话中
查看消息
,这将带您进入另一个会话中的新控制台,您可以从中运行jvmdump.bat
脚本。The following script uses PsExec to connect to another Windows Session so it works even when connected via Remote Desktop Service.
I wrote a small batch script for Java 8 (using
PsExec
andjcmd
) namedjvmdump.bat
, which dumps the threads, heap, system properties, and JVM args.It must be run in the same Windows session of the user that started the JVM, so if you connect through Remote Desktop you might need to launch a command prompt in
Session 0
and run it from there. e.g.This will prompt you (click the taskbar icon at the bottom) to
View the message
in the interactive session, which will take you to the new console in the other session from which you can run thejvmdump.bat
script.如果您使用的是 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工具,使用起来很简单。
If you are using JDK 1.6 or above, You can use
jmap
command to take a heap Dump of a Java process, condition is you should known ProcessID.If you are on Windows Machine, you can use Task Manager to get PID. For Linux machine you can use varieties of command like
ps -A | grep java
ornetstat -tupln | grep java
ortop | grep java
, depends on your application.Then you can use the command like
jmap -dump:format=b,file=sample_heap_dump.hprof 1234
where 1234 is PID.There are varieties of tool available to interpret the hprof file. I will recommend Oracle's visualvm tool, which is simple to use.
如果由于某种原因您不能(或不想)使用控制台/终端,还有一个替代解决方案。 您可以让 Java 应用程序为您打印线程转储。 收集堆栈跟踪的代码相当简单,可以附加到按钮或 Web 界面。
此方法将返回一个如下所示的字符串:
对于那些对带有流的 Java 8 版本感兴趣的人,代码更加紧凑:
您可以使用以下命令轻松测试此代码:
If you can't (or don't want) to use the console/terminal for some reason, there is an alternative solution. You can make the Java application print the thread dump for you. The code that collects the Stack Trace is reasonable simple and can be attached to a button or a web interface.
This method will return a string that looks like this:
For those interested in a Java 8 version with streams, the code is even more compact:
You can easily test this code with:
为了从 Windows 中的子 java 进程获取线程转储/堆转储,您需要首先识别子进程 ID。
通过发出命令:jps,您将能够获取 Windows 计算机上运行的所有 java 进程 ID。 您需要从此列表中选择子进程 ID。 一旦有了子进程 ID,就可以使用各种选项来捕获线程转储和堆转储。
捕获线程转储:
有 8 个选项可捕获线程转储:
有关每个选项的详细信息,请参阅 本文。 捕获线程转储后,您可以使用 fastThread、Samuraito 分析线程转储。
捕获堆转储:
有 7 个选项可以捕获堆转储:
jmap
-XX:+HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
编程方法
管理控制台
有关每个选项的详细信息可以在本文中找到。 捕获堆转储后,您可以使用 Eclipse 内存分析工具、HeapHero 来分析捕获的堆转储。
Inorder to take thread dump/heap dump from a child java process in windows, you need to identify the child process Id as first step.
By issuing the command: jps you will be able get all java process Ids that are running on your windows machine. From this list you need to select child process Id. Once you have child process Id, there are various options to capture thread dump and heap dumps.
Capturing Thread Dumps:
There are 8 options to capture thread dumps:
Details about each option can be found in this article. Once you have capture thread dumps, you can use tools like fastThread, Samuraito analyze thread dumps.
Capturing Heap Dumps:
There are 7 options to capture heap dumps:
jmap
-XX:+HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
Programmatic Approach
Administrative consoles
Details about each option can be found in this article. Once you have captured heap dump, you may use tools like Eclipse Memory Analysis tool, HeapHero to analyze the captured heap dumps.
也许jcmd?
Jcmd 实用程序用于向 JVM 发送诊断命令请求,这些请求对于控制 Java 飞行记录、排除故障以及诊断 JVM 和 Java 应用程序非常有用。
jcmd 工具是随 Oracle Java 7 一起引入的,通过使用它来识别 Java 进程的 ID(类似于 jps)、获取堆转储(类似于 jmap)、获取线程转储(类似于 jstack),在解决 JVM 应用程序问题时特别有用。 ),查看虚拟机特征,例如系统属性和命令行标志(类似于 jinfo),以及获取垃圾收集统计信息(类似于 jstat)。 jcmd 工具被称为“用于调查和解决 JVM 应用程序问题的瑞士军刀”和“隐藏的宝石”。
以下是调用
jcmd
时需要使用的流程:jcmd GC.heap_dump
查看有关获取 Java 堆转储 的更多信息。
Maybe jcmd?
Jcmd utility is used to send diagnostic command requests to the JVM, where these requests are useful for controlling Java Flight Recordings, troubleshoot, and diagnose JVM and Java Applications.
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."
Here’s the process you’ll need to use in invoking the
jcmd
:jcmd <pid> GC.heap_dump <file-path>
Check it out for more information about taking Java heap dump.
下面的java代码用于通过提供远程进程的PID来获取Java进程的堆转储。 该程序使用远程 JMX 连接将堆转储到文件。 这可能对某些人有帮助。 不需要 jmap。
}
Below java code is used to get the Heap Dump of a Java Process by providing a remote process' PID. The Program uses Remote JMX connection to dump heap to a file. It may be helpful for some one. Doesn't require jmap.
}
Visualvm 后续:
如果由于没有使用正确的 JVM 参数启动它(并且它位于远程机器上),因此无法从 jvisualvm“连接”到正在运行的 JVM,请在远程机器上运行
jstatd
,然后,假设您有直接连接,将其添加为 VisualVM 中的“远程主机”,双击主机名,该框中的所有其他 JVM 将神奇地显示在 VisualVM 中。如果您没有到该盒子上的端口的“直接连接”,您也可以通过 代理。
一旦您可以看到所需的进程,请在 jvisualvm 中深入研究它并使用“监视器”选项卡 ->; “堆转储”按钮。
Visualvm followup:
If you "can't connect" to your running JVM from jvisualvm because you didn't start it with the right JVM arguments (and it's on remote box), run
jstatd
on the remote box, then, assuming you have a direct connection, add it as a "remote host" in visualvm, double click the host name, and all other JVM's on that box will magically show up in visualvm.If you don't have "direct connection" to ports on that box, you can also do this through a proxy.
Once you can see the process you want, drill into it in jvisualvm and use monitor tab -> "heapdump" button.
在 Oracle JDK 上,我们有一个名为 jmap 的命令(可在 Java Home 的 bin 文件夹中找到)。
命令的用法如下
示例:jmap -dump:live,format=b,file=heap.bin (pid)
On a Oracle JDK, we have a command called jmap (available in the bin folder of Java Home).
usage of the command comes as follows
Example: jmap -dump:live,format=b,file=heap.bin (pid)