← Back to list

Could not open PerfMemory 问题

Published on: | Views: 117

这是一个偶然出现的问题 背景是在某个客户的服务器上(Windows Server 2012),使用WinSW将应用安装为服务,在应用中调用getMonitoredVm获取外部程序信息时,出现了没有权限的异常。

错误日志

java.lang.Exception: Could not open PerfMemory
    at sun.misc.Perf.attach(Native Method) ~[?:1.8.0_41]
    at sun.misc.Perf.attachImpl(Perf.java:270) ~[?:1.8.0_41]
    at sun.misc.Perf.attach(Perf.java:200) ~[?:1.8.0_41]
    at sun.jvmstat.perfdata.monitor.protocol.local.PerfDataBuffer.<init>(PerfDataBuffer.java:64) ~[tools.jar!/:?]
    at sun.jvmstat.perfdata.monitor.protocol.local.LocalMonitoredVm.<init>(LocalMonitoredVm.java:68) ~[tools.jar!/:?]
    at sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostProvider.getMonitoredVm(MonitoredHostProvider.java:77) ~[tools.jar!/:?]
    at sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostProvider.getMonitoredVm(MonitoredHostProvider.java:67) ~[tools.jar!/:?]

根据错误信息,找到了这个:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6495549 里面提到,虚拟机是将进程信息写到%TMP%\hsperfdata_目录中,如果访问不到此目录,就会报错 根据上面的建议,我修改了环境变量TMP(Control Panel -> System -> Advanced -> Environment Variables),指向了自己建的目录C:\TEMP, 重启了机器,问题并没有得到解决。

尝试手动运行程序(不用winsw),发现能正常运行,猜测原因可能是winsw使用的账户localservice运行程序时,其临时目录有问题,访问不到。

于是修改配置文件,增加指定临时目录

<env name="TMP" value="C:\TEMP"/>

然后运行,发现一切正常了,除了时间又流失了几个小时 :( 查看TMP目录,发现新建了一个子目录:C:\TEMP\hsperfdata_iZgt0gufxxxxXXX$, 里面有一些数字命名的文件。