如何在Java中读取用于Java进程的Windows“虚拟字节”性能计数器?

时间:2012-02-22 16:31:39

标签: java java-native-interface monitoring performancecounter

也许使用jniwrap.jar and winpack.jar所以我不必滚动自己的JNI代码,如何读取Java服务的“虚拟字节”性能计数器?该服务将读取其自己的性能计数器,以便它可以定期记录正在使用的虚拟地址空间。目前,它记录了OS JMX MBean返回的JMX值“CommittedVirtualMemorySize”,但这仅显示已提交的内存量,因此无法真正帮助您了解是否即将耗尽你的虚拟地址空间。

这适用于基于Java的服务器进程,有时Java编译器线程会耗尽C堆,从而导致整个JVM崩溃。我自己的代码不是罪魁祸首 - 它是JVM本身。但是这个诊断数据将帮助我理解服务的完整虚拟地址空间需求。

编辑:自从提出这个问题以来,我尝试了几个不同的东西,到目前为止无济于事。事实证明,winpack.jar允许注册表访问,并且有一个注册表项RegistryKey.PERFORMANCE_DATA,它可以通过类似注册表的访问提供对性能数据的访问,但我总是没有键回来。我在VB中发现了一些使用此方法获取性能数据的sample code,即使使用该代码,我也没有获得任何数据。这是在Win7Pro桌面上。这些数据默认不可用吗?

如果我无法使用该方法,那么我认为唯一的另一种选择是尝试使用jniwrap或winpack以某种方式在Java中执行与此C#代码等效的代码:

PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "Virtual Bytes";
PC.InstanceName = "Java#1";
PC.ReadOnly = true;
float VirtualBytes = PC.NextValue();

但我想不出一个好方法。是否有人熟悉Jniwrapper / winpack或通过注册表获取性能数据谁可以建议这样做?

我认识到总是有可能编写一个外部C#程序或WMI脚本来获取这些信息,但我希望这比获得对这些信息的直接编程访问要慢一些(并且要实现更多工作)。 / p>

1 个答案:

答案 0 :(得分:0)

事实证明WinPack.jar库direclty提供了这些信息!我没有找到任何帮助我找到这个的文档。只需查看其API文档和实验,我就能够提出这段代码。如果您使用的是最新版本的库,请将MemoryStatus替换为MemoryInfo

import com.jniwrapper.win32.system.MemoryStatus;

...

private void test() {
  MemoryStatus mStatus = new MemoryStatus();
  System.out.println("TotalVirtual: " + getBytesInMB(mStatus.getTotalVirtual()) + " MB");
  System.out.println("AvailVirtual: " + getBytesInMB(mStatus.getAvailVirtual()) + " MB");
  System.out.println("UsedVirtual:  " + getBytesInMB(mStatus.getTotalVirtual() - mStatus.getAvailVirtual()) + " MB");
}

private long getBytesInMB(final long input) {
  return input / 1024 / 1024;
}

这给了我正在寻找的东西 - 运行此代码的Java进程的虚拟地址空间使用情况。它不是一个通用的解决方案,但它可以帮助其他想要记录相同类型信息的人。