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

发布于 2025-01-08 06:14:08 字数 1191 浏览 0 评论 0原文

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

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

编辑:自从问这个问题以来,我尝试了几种不同的方法,但到目前为止没有结果。事实证明,winpack.jar 允许注册表访问,并且有一个注册表项 RegistryKey.PERFORMANCE_DATA 据说可以通过类似注册表的访问来提供对性能数据的访问,但我总是没有得到任何密钥。我在VB中找到了一些使用此方法获取性能数据的示例代码,并且即使使用该代码,我也没有返回任何数据。这是在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 脚本来获取此信息,但我预计这比直接以编程方式访问此信息要慢几个数量级(并且需要执行更多工作)。

Perhaps making use of jniwrap.jar and winpack.jar so I don't have to roll my own JNI code, how can I read the "Virtual Bytes" performance counter for a Java service? The service will read its own performance counter so that it can periodically log how much virtual address space is in use. Currently, it logs the JMX value "CommittedVirtualMemorySize" returned by the OS JMX MBean, but this only shows the amount of memory that is committed, so doesn't really help you understand if you are about to exhaust your virtual address space.

This is for a Java-based server process where sometimes the Java compiler thread exhausts the C Heap, crashing the whole JVM in the process. My own code is not the culprit -- it's the JVM itself. But this diagnostic data will help me understand the full virtual address space needs of the service.

Edit: Since asking this question, I have tried several different things, so far to no avail. It turns out that winpack.jar allows registry access and there is a registry key RegistryKey.PERFORMANCE_DATA that supposedly provides access to performance data via registry-like access, but I always got no keys back. I found some sample code in VB that used this method to get performance data, and even with that code, I got back no data. This is on a Win7Pro desktop. Is this data not available by default?

If I cannot get that method to work, then I think the only other choice is trying to use jniwrap or winpack to somehow execute code in Java equivalent to this C# code:

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

but I can't think of a good way to do this. Is there anyone familiar either with Jniwrapper/winpack or with getting performance data via the registry who can suggest a way of doing this?

I recognize there's always the possibility of writing an external C# program or WMI script to get this information, but I expect that to be orders of magnitude slower (and more work to implement) than getting direct programmatic access to this information.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

澜川若宁 2025-01-15 06:14:08

事实证明, WinPack.jar 库直接提供了此信息!我没有找到任何帮助我找到这个的文档。只要浏览它的 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 进程的虚拟地址空间使用情况正在运行这段代码。它不是通用解决方案,但它可能会帮助其他想要记录同类信息的人。

It turns out that the WinPack.jar library direclty provides this information! I didn't find any documentation that helped me find this. Just looking through its API documentation and experimenting, I was able to come up with this code. Replace MemoryStatus with MemoryInfo if you're using the latest version of the library:

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;
}

this gives me what I am looking for -- the virtual address space usage of the Java process that is running this code. It is not a general purpose solution, but it may help other people who want to log the same kind of information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文