为了账号安全,请及时绑定邮箱和手机立即绑定

如何在未在控制台中运行的Windows上获取Java进程的线程和堆转储

/ 猿问

如何在未在控制台中运行的Windows上获取Java进程的线程和堆转储

阿波罗的战车 2019-10-23 14:39:17

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


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


还有另一种方法来获得该堆转储吗?


查看完整描述

3 回答

?
慕仰8121524

jmap假设您知道,则可以使用来获取正在运行的任何进程的转储pid。


使用任务管理器或资源监视器获取pid。然后


jmap -dump:format=b,file=cheap.hprof <pid>

获得该进程的堆。


查看完整回答
反对 回复 2019-10-23
?
慕哥6287543

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


线程转储= JVM输出到stdout的每个线程的堆栈跟踪作为文本。


堆转储= JVM进程输出到二进制文件的内存内容。


要在Windows上进行线程转储,CTRL+(BREAK如果JVM是前台进程)是最简单的方法。如果在Windows上(例如Cygwin或MobaXterm)具有类unix的外壳,则可以kill -3 {pid}像在Unix中一样使用。


要在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


只是为了解决转储问题:堆转储不常用,因为它们难以解释。但是,如果您知道在哪里/如何查看它们,它们中就会包含很多有用的信息。最常见的用法是查找内存泄漏。最好-D在java命令行上设置,以便在OutOfMemoryError时自动生成堆-XX:+HeapDumpOnOutOfMemoryError 转储。但是,您也可以手动触发堆转储。最常见的方法是使用java实用程序jmap。


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


一个示例命令行看起来像


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

对于我们大多数人来说,输出“ myheap.bin”是不可读的,您将需要一个工具来对其进行分析。我的偏好是MAT。 http://www.eclipse.org/mat/


查看完整回答
反对 回复 2019-10-23
?
临摹微笑

除了使用提到的jconsole / visualvm,您还可以jstack -l <vm-id>在另一个命令行窗口上使用并捕获该输出。


可以使用任务管理器(它是Windows和UNIX上的进程ID)或使用来找到<vm-id> jps。


两者jstack和jps都包含在Sun JDK版本6和更高版本中。


查看完整回答
反对 回复 2019-10-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信