18

我正在尝试使用本地运行的 JVisualVM(JDK 1.7.0 - 06、64 位)将在 Apache Tomcat(7.0.34)中运行的 Servlet 作为 Windows 7(64 位)上的服务进行分析。

最初,由于不同的“java.io.tmp”属性错误/功能,我遇到了 Tomcat 未显示在本地应用程序列表中的问题,但按照本论坛中几篇文章的建议解决了这个问题。

然而,尽管 Tomcat 进程现在在本地应用程序列表中显示为“本地应用程序”,但当我打开进程时,没有监视器、线程、采样器或配置文件的选项卡 - 只有 JVM 参数和系统属性子的概览选项卡-tabs 显示可怕的“此 jvm 不支持”消息。

我已经仔细检查了以下项目:

  • 通过查看 JVisualVM 中的 JVM 属性(使用 Tomcat 的 JMX 连接),Tomcat 和 JVisualVM 都在运行相同版本的 Java
  • 通过查看 JVisualVM 中的系统属性(再次使用 Tomcat 的 JMX 连接)并查看实际的 TMP/TEMP 目录并确认两者的 PID 文件,Tomcat 和 JVisualVM 都具有相同的“java.io.tmp”路径存在
  • 文件系统是 NTFS
  • Windows 用户的名称中没有下划线(注意:用户的名称中确实有句点,因为我们使用的是“firstname.lastname”形式的网络登录,但是我在 JVisualVM 中查看其他 Java 应用程序没有问题所以不要认为这是一个问题)
  • 通过查看任务管理器中的进程,Tomcat 和 JVisualVM 都作为同一个 Windows 用户执行

最后几点:

  • 我需要分析Servlet,因此使用 JMX 是不够的
  • 我能够在 Windows XP 机器(Java 7、Tomcat 7 即服务)上进行分析,所以这似乎是 Windows 7 / 64 位的东西?

如果有人已经解决了这个问题,显然这个解决方案将不胜感激。但是,如果其他人正在运行相同的配置(Windows 7 64 位、Java 7 64 位、Tomcat 7 作为服务运行),这将很有

更新:我没有作为服务运行,而是使用批处理文件运行 Tomcat,并且一切正常:作为服务运行有什么意义?

4

4 回答 4

10

正如我之前的评论中已经暗示的那样。我想简单的答案是不可能的。为了实现jconsole/jvisualvm与被监控进程之间的通信,Java使用了内存映射文件。最后归结为某个 Windows API 调用由于 Windows Vista 中添加的“Windows 服务强化”[1] 功能而失败,当然,Windows 7 和更高版本中也存在该功能。

失败的调用是对函数 OpenFileMapping 的调用,如 perfMemory_windows.cpp 第 1402 行 [2] 中所示。在我的实验中,该方法使用“hsperfdata_[username]_[process id]”形式的参数调用。正如微软对服务强化(参见 [3])引入的差异的进一步详细说明,如果不使用名称前缀,通信将不起作用:“如果用户应用程序 [...] 通过创建或打开来与服务同步带有 Local\ 前缀(或无前缀,默认为 Local)的对象,应用程序不再按预期工作。”

如果有人想亲自看看。您可以使用 Windows 调试工具中包含的 Logger 工具 [4] 来跟踪 API 调用。

此外,Sysinternals Process Explorer 非常方便,因为它通过其“查找句柄或 DLL...”功能显示用于内存映射文件的全名。只需搜索包含“hsperf”的句柄。

附带说明:删除或以其他方式弄乱包含 hsperf 数据的临时目录的解决方法归结为要监视的进程和监视进程使用的用户名的大小写需要一致。但除了更改临时目录之外,您还可以轻松更改监控进程使用的 USERNAME 环境变量。您还可以在 perfMemory_windows.cpp 第 272 行 [2] 中查看它是如何使用的。

[1] http://technet.microsoft.com/en-us/library/cc507844.aspx#EHF

[2] http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/file/5dce25362b8a/src/os/windows/vm/perfMemory_windows.cpp

[3] http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx

[4] http://msdn.microsoft.com/en-us/library/windows/hardware/ff560123(v=vs.85).aspx

于 2014-01-27T16:46:45.867 回答
7

你几乎做到了“我没有作为服务运行,而是使用批处理文件运行 Tomcat,并且一切运行良好:作为服务运行是什么”现在剩下的唯一步骤是将 JVisualVM 作为服务运行 :)

参考这个

https://blogs.oracle.com/nbprofiler/entry/monitoring_java_processes_running_as

由于只能分析在与 VisualVM 相同的用户下运行的 Java 进程,因此分析 Windows 服务(默认情况下在系统帐户下运行)的唯一方法是将 VisualVM 本身作为 Windows 服务启动。请注意,由于安全限制默认情况下会阻止服务显示任何 UI,因此此方法在 Windows Vista 上不起作用。

另一种选择是运行 Run CMD.EXE as Local System ,请参阅下文。

http://vicevoice.blogspot.in/2009/09/vaas-visualvm-as-service.html

于 2013-02-18T11:53:22.853 回答
2

你不能只是通过网络连接,即启动JVM

 java 
  -Dcom.sun.management.jmxremote
  -Dcom.sun.management.jmxremote.port=1234 
  -Dcom.sun.management.jmxremote.local.only=false 
  -Dcom.sun.management.jmxremote.authenticate=false 
  -Dcom.sun.management.jmxremote.ssl=false 
  -jar my.jar`

并在工具中创建到 localhost:1234 的网络连接

于 2014-01-27T22:31:59.147 回答
0

如果有人在 Windows 7 上有解决方案,我也很好奇。正如前面提到的,将 VisualVM 作为服务运行的技巧在 Vista 上不起作用,我假设相同的安全功能阻止它在 Win 7 上运行。

我唯一的解决方案是将您的应用服务器(Tomcat)设置为服务,这样如果服务器重新启动,它就会启动并可用。然后手动停止服务并从命令行启动您的应用服务器 (Tomcat) 并与 VisualVM 连接。只要服务器没有重新启动,你就可以得到很好的监控。

于 2013-07-15T17:59:18.860 回答