无法使用Windows 7上作为服务运行的Tomcat7的JVisualVM分析

我尝试使用本地运行的JVisualVM(JDK 1.7.0 – 06,64位)将在Apache Tomcat(7.0.34)中运行的Servlet作为Windows 7(64位)上的服务进行configuration文件。

最初,由于不同的“java.io.tmp”属性错误/function,Tomcat没有在本地应用程序列表中显示问题,而是按照本论坛中几篇文章中的build议解决了这个问题。

然而,尽pipeTomcat进程现在在本地应用程序列表中显示为“本地应用程序”,但是当我打开进程时,Monitor,Threads,Sampler或Profile没有标签 – 只有JVM参数和Sytem Properties子标签-tabs显示可怕的“不支持这个jvm”的消息。

我有双重检查下列项目:

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

几个最后的观点:

  • 我需要使用JMX来剖析Servlet是不够的
  • 我能够在Windows XP机器上进行configuration文件(Java 7,Tomcat 7作为服务),所以似乎是Windows 7/64位的东西?

如果有人已经解决了这个问题,显然解决scheme将不胜感激。 然而,只要知道其他人是否正在运行相同的configuration(Windows 7 64位,Java 7 64位,作为服务运行的Tomcat 7),就会很有用。

更新:作为一个服务而不是运行,我使用batch file运行Tomcat,所有工作都很完美:作为服务运行是什么?

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

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

如果有人想自己看看。 您可以使用Windows调试工具附带的Logger工具[4]来跟踪API调用。

此外Sysinternals进程资源管理器是非常方便的,因为它显示通过其“查找句柄或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

你几乎做到了“ 不用运行服务,我使用批处理文件运行Tomcat,所有工作都完美:作为服务运行的是什么 ”现在唯一剩下的就是运行JVisualVM作为服务:)

参考这个

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

由于只有与VisualVM在同一用户下运行的Java进程可以进行配置,所以配置Windows服务(默认情况下在System帐户下运行)的唯一方法是启动VisualVM本身作为Windows服务。 请注意,此方法在Windows Vista上不起作用,这是由于默认情况下会阻止服务显示任何UI的安全限制。

另一个选项是运行CMD.EXE作为本地系统,请参阅下文。

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

你不能只通过网络连接,即启动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的网络连接

我也很好奇,如果有人在Windows 7上有一个解决方案。如上所述,作为服务运行VisualVM的技巧不适用于Vista,我假设相同的安全功能阻止它在Win 7上工作。

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