如何在未在控制台中运行的 Windows 上获取 Java 进程的线程和堆转储
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/407612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get a thread and heap dump of a Java process on Windows that's not running in a console
提问by
I have a Java application that I run from a console which in turn executes an another Java process. I want to get a thread/heap dump of that child process.
我有一个从控制台运行的 Java 应用程序,它依次执行另一个 Java 进程。我想获得该子进程的线程/堆转储。
On Unix, I could do a kill -3 <pid>
but on Windows AFAIK the only way to get a thread dump is Ctrl-Break in the console. But that only gives me the dump of the parent process, not the child.
在 Unix 上,我可以这样做,kill -3 <pid>
但在 Windows AFAIK 上,获取线程转储的唯一方法是控制台中的 Ctrl-Break。但这只会给我父进程的转储,而不是子进程。
Is there another way to get that heap dump?
有没有另一种方法来获得堆转储?
回答by krosenvold
You can send the kill -3 <pid>
from Cygwin. You have to use the Cygwin ps
options to find windows processes then just send the signal to that process.
您可以kill -3 <pid>
从 Cygwin发送。您必须使用 Cygwinps
选项来查找 Windows 进程,然后将信号发送到该进程。
回答by Yoni Roit
You have to redirect output from second java executable to some file. Then, use SendSignalto send "-3"to your second process.
您必须将输出从第二个 java 可执行文件重定向到某个文件。然后,使用SendSignal来发送“-3”你的第二个过程。
回答by Steve Kuo
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.
您可以运行jconsole
(包含在 Java 6 的 SDK 中)然后连接到您的 Java 应用程序。它将向您显示每个正在运行的线程及其堆栈跟踪。
回答by Lawrence Dol
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.
我推荐与 JDK 一起分发的 Java VisualVM (jvisualvm.exe)。它可以动态连接并访问线程和堆。我发现在一些问题上是无价的。
回答by ankon
In addition to using the mentioned jconsole/visualvm, you can use jstack -l <vm-id>
on another command line window, and capture that output.
除了使用提到的 jconsole/visualvm 之外,您还可以jstack -l <vm-id>
在另一个命令行窗口上使用,并捕获该输出。
The <vm-id> can be found using the task manager (it is the process id on windows and unix), or using jps
.
<vm-id> 可以使用任务管理器找到(它是 windows 和 unix 上的进程 ID),或者使用jps
.
Both jstack
and jps
are include in the Sun JDK version 6 and higher.
两者jstack
并jps
有包括6和更高太阳的JDK版本。
回答by rkaganda
You can use jmap
to get a dump of any process running, assuming you know the pid
.
您可以使用jmap
来获得任何进程运行的转储,假设你知道的pid
。
Use Task Manager or Resource Monitor to get the pid
. Then
使用任务管理器或资源监视器获取pid
. 然后
jmap -dump:format=b,file=cheap.hprof <pid>
to get the heap for that process.
获取该进程的堆。
回答by Daniel Winterstein
If you want a heapdump on out-of-memory, you can start Java with the option -XX:-HeapDumpOnOutOfMemoryError
如果您想在内存不足时进行堆转储,您可以使用以下选项启动 Java -XX:-HeapDumpOnOutOfMemoryError
回答by Derek
You are confusing two different java dumps. kill -3
generates a thread dump, not a heap dump.
您混淆了两个不同的 Java 转储。 kill -3
生成线程转储,而不是堆转储。
Thread dump = stack traces for each thread in the JVM output to stdout as text.
Heap dump = memory contents for the JVM process output to a binary file.
线程转储 = JVM 中每个线程的堆栈跟踪以文本形式输出到标准输出。
堆转储 = JVM 进程输出到二进制文件的内存内容。
To take a thread dump on Windows, CTRL+BREAKif 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.
要在 Windows 上进行线程转储,如果您的 JVM 是前台进程,则CTRL+BREAK是最简单的方法。如果你在 Windows 上有一个类似 Unix 的 shell,比如 Cygwin 或 MobaXterm,你可以kill -3 {pid}
像在 Unix 中一样使用。
To take a thread dump in Unix, CTRL+Cif your JVM is the foreground process or kill -3 {pid}
will work as long as you get the right PID for the JVM.
要在 Unix 中进行线程转储,CTRL+C如果您的 JVM 是前台进程,或者kill -3 {pid}
只要您为 JVM 获得正确的 PID 就可以工作。
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.html
无论是哪种平台,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
.
只是为了完成转储问题:堆转储不常用,因为它们难以解释。但是,如果您知道在哪里/如何查看它们,它们就会包含很多有用的信息。最常见的用法是定位内存泄漏。-D
在 java 命令行上设置 是一个很好的做法,以便在 OutOfMemoryError 时自动生成堆转储,-XX:+HeapDumpOnOutOfMemoryError
但是,您也可以手动触发堆转储。最常见的方法是使用 java 实用程序jmap
。
NOTE:this utility is not available on all platforms. As of JDK 1.6, jmap
is available on Windows.
注意:此实用程序并非在所有平台上都可用。从 JDK 1.6 开始,jmap
可在 Windows 上使用。
An example command-line would look something like
一个示例命令行看起来像
jmap -dump:file=myheap.bin {pid of the JVM}
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/
输出“myheap.bin”不是人类可读的(对我们大多数人来说),你需要一个工具来分析它。我的偏好是MAT。 http://www.eclipse.org/mat/
回答by Roberto Flores
I think the best way to create .hprof file in Linux process is with jmapcommand. For example: jmap -dump:format=b,file=filename.hprof {PID}
我认为在 Linux 进程中创建 .hprof 文件的最佳方法是使用jmap命令。例如:jmap -dump:format=b,file=filename.hprof {PID}
回答by Badal
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.
如果您使用的是 JDK 1.6 或更高版本,您可以使用jmap
命令来获取 Java 进程的堆转储,条件是您应该知道 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
or netstat -tupln | grep java
or top | grep java
, depends on your application.
如果你在 Windows 机器上,你可以使用任务管理器来获取 PID。对于 Linux 机器,您可以使用各种命令,例如ps -A | grep java
或 netstat -tupln | grep java
或top | grep java
,具体取决于您的应用程序。
Then you can use the command like jmap -dump:format=b,file=sample_heap_dump.hprof 1234
where 1234 is PID.
然后你可以使用像jmap -dump:format=b,file=sample_heap_dump.hprof 1234
where 1234 is PID这样的命令。
There are varieties of tool availableto interpret the hprof file. I will recommend Oracle's visualvm tool, which is simple to use.
有多种工具可用于解释 hprof 文件。我会推荐Oracle的visualvm工具,使用起来很简单。