jvisualvm无法列出某些Java进程

41
我想获取某个Java进程的堆转储文件(怀疑内存泄漏)。但是,当我启动jvisualvm工具时,我无法看到任何正在运行的Java进程。
我在谷歌上搜索了相关信息,并已经找到几篇文章说,你必须使用与启动jvisualvm工具相同的JDK来运行Java进程,以便它能够看到它们。然而,据我所见,这已经是事实。我在本地进行所有操作(我可以远程访问该计算机)。
需要考虑以下几点:
  1. 进程正在防火墙保护下的Windows 2008服务器上运行
  2. 进程使用已重命名的JDK java.exe可执行文件运行
  3. 据我所见,进程正在使用1.6.0_18 JDK运行
  4. 其中一个正在运行的进程启动了RMI注册表
我正在等待服务器的虚拟副本,以便对其进行调试(这是生产服务器)。但在此期间,您有什么想法,为什么我无法在jvisualvm(或jconsole)中看到任何进程?

为什么要重命名java.exe?我非常确定VisualVM通过查找所有运行java.exe的进程来获取其进程列表。 - Gandalf
在Windows中,您无法轻松查看命令行参数,因此最终会重命名/复制java.exe,以便知道哪个进程是什么。 - Peter Lawrey
7
jconsole和visualvm是针对特定用户的工具。如果进程以另一个用户身份运行,则您将无法看到它们,但是您可以打开安全性以允许通过“远程”方式进行管理。 - Peter Lawrey
谢谢你的提示,那很可能就是原因。这些进程是通过Windows服务启动的,所以它们可能在某个Windows服务账户下运行。你能提供一些相关文章的链接吗?如果可以的话,请将其作为答案提供,我会批准它是否正确。 - tmbrggmn
7
如果您想查看运行在Windows机器上的程序,包括完整的命令行参数、TCP/IP套接字等,那么您应该使用Sysinternals Process Explorer。它类似于功能强大的任务管理器。作为开发人员,一旦您尝试过它,您将会希望在任何使用Windows的机器上都安装它。Sysinternals套件中还有许多其他非常有用的工具,例如Junction,在Windows上提供了真正的类Unix符号链接。 - crowne
2个回答

67

我做了一些研究后发现,彼得的评论是正确的。由于JVM进程是由另一个用户(NETWORK SERVICE账户,因为它们是由Windows服务启动的)启动的,所以它们没有显示在jvisualvm中。

解决方法

既然我可以访问应用程序配置,我已经找到了以下解决方法,它涉及显式启用目标JVM的未安全的JMX:

  1. 添加以下JVM参数:

    -Dcom.sun.management.jmxremote.port=3333 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

  2. 使用JMX将远程进程添加到jvisualvm中,方法是点击 文件 -> 添加JMX连接。您可以使用端口号3333连接到进程。如果需要,您当然可以更改端口。

详细说明文章链接http://download.oracle.com/javase/6/docs/technotes/guides/visualvm/jmx_connections.html

注意事项

  1. 长期保留JVM设置可能不是一个好主意,因为它们将允许任何人通过JMX连接到JVM。
  2. 如果需要,您还可以向JMX JVM参数添加身份验证。

是的,+1。我一直被这个困扰着。在Linux上也是这样吗? - David Brossard
1
@DavidBrossard 我想象它是这样的,或者至少存在一种类似的机制来限制某些服务,就像Windows所做的那样。 - tmbrggmn

8

最简单的方法是以管理员身份运行jvisualvm(win:“以管理员身份运行”)。这不是理想的方案,但是可行的。然后所有Java进程都会显示出来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接