Java(Windows)-通过进程ID,获取内存使用情况,磁盘使用情况,网络使用情况 [英] Java (Windows) - By process id, get memory usage, disk usage, network usage

查看:821
本文介绍了Java(Windows)-通过进程ID,获取内存使用情况,磁盘使用情况,网络使用情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究针对特定过程获取以下数据的最佳方法:

I've been investigating the best approach to achieve the following data for a specific process:

  1. CPU使用率
  2. 内存使用量
  3. 磁盘使用情况
  4. 网络使用情况

我决定使用OSHI(操作系统和硬件信息)API. 对我来说不幸的是,该API并没有为我提供所需的信息,它需要一些有关如何计算的基本知识,例如每个进程的CPU使用率.

I decided to go with OSHI (Operating system & hardware information) API. Unfortunate for me , this API isn't giving me the desired info out of the box, it requires some basic knowledge of how to calculate , for example the cpu usage per process.

我的问题是:如何通过进程ID获取内存,磁盘,网络使用情况?

使用以下每个示例的CPU使用率数据示例

using the following example of cpu usage data per prcoess

例如:

要获取claculator.exe运行进程的实际CPU使用率,请执行以下操作:

To get the actual CPU usage of a claculator.exe running process:

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;

public class processCPUusage {
    public static void main(String[] args) throws InterruptedException {
        OSProcess process;
        long currentTime,previousTime = 0,timeDifference;
        double cpu;
        int pid = 7132;
        SystemInfo si = new SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        CentralProcessor processor = si.getHardware().getProcessor();
        int cpuNumber = processor.getLogicalProcessorCount();
        boolean processExists = true;
        while (processExists) {
            process = os.getProcess(pid); // calculator.exe process id
            if (process != null) {
                // CPU
                currentTime = process.getKernelTime() + process.getUserTime();

                if (previousTime != -1) {
                    // If we have both a previous and a current time
                    // we can calculate the CPU usage
                    timeDifference = currentTime - previousTime;
                    cpu = (100d * (timeDifference / ((double) 1000))) / cpuNumber;
                    System.out.println(cpu);
                }     

                previousTime = currentTime;

                Thread.sleep(1000);
            } else {
                processExists = false;
            }
        }
    }
}

我正在使用的框架 https://github.com/oshi/oshi/tree/master/src/site/markdown 演示了所需的功能,但缺少适当的示例

The framework I'm using https://github.com/oshi/oshi/tree/master/src/site/markdown demonstrates the desired functionality but lacks proper examples

  • 语言:Java 8
  • 构建工具:Maven 2
  • 操作系统:Windows 10 *

OSHI库+ slf4j

OSHI library + slf4j

    <dependency>
        <groupId>com.github.dblock</groupId>
        <artifactId>oshi-core</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
    </dependency>

推荐答案

以下2017年的原始答案现在已过时. OSProcess类现在具有更多的方法,这些方法大多可以回答原始请求.

The original answer in 2017 below is now out of date. The OSProcess class now has many more methods that mostly answer the original request.

Shikari的答案适用于手动计算.我还将注意到从版本5.x开始的OSProcess对象上存在方法getProcessCpuLoadBetweenTicks(),该方法将为您进行CPU计算.

The answer by Shikari is good for manual calculations. I'll also note the presence of a method getProcessCpuLoadBetweenTicks() on the OSProcess object starting in version 5.x that will do the CPU calculation for you.

下面的上一个答案:

我是在您要引用的OSHI中实现OSProcess类的人,并且一直在与该项目的Issue中与您进行交流.

I am the one who implemented the OSProcess class in OSHI that you are referencing, and have been communicating with you in an Issue on that project.

虽然OSHI当前未提供OSProcess界面中的所有功能,但确实为您提供了对WMI类的访问方法,这些方法将为您提供所需的所有信息.如果您查看 WindowsOperatingSystem 类可实现您正在使用的getProcess()方法,您可以使用WMIUtil复制/修改代码以直接获取所需的信息.

While OSHI does not currently provide all the functionality in the OSProcess interface, it does provide you access methods to the WMI classes which will provide you all the information you seek. If you take a look at the WindowsOperatingSystem class which implements the getProcess() method you're using, you can copy/modify the code using WMIUtil to directly fetch the bits of information that you need.

OSHI当前从 Win32_Process WMI类,但正如我在此问题上提到的那样,最好从 Win32_PerfFormattedData_PerfProc_Process .在这些课程中,您可以找到:

OSHI currently fetches from the Win32_Process WMI class but as I've mentioned on the issue, it might be better to get information instead from Win32_PerfRawData_PerfProc_Process (which provides the raw data you can use for direct calculations) or Win32_PerfFormattedData_PerfProc_Process. In these classes you can find:

CPU使用率

  • 经过时间
  • PercentPrivilegedTime
  • PercentProcessorTime
  • PercentUserTime

(请注意,原始名称实际上表示百分比",原始数据实际上包括递增的滴答"))

(Note while the name says "Percent" the raw data actually includes incrementing "ticks")

内存使用情况

  • VirtualBytes
  • WorkingSet

磁盘使用率,网络使用率

  • IOReadBytesPerSec;
  • IOWriteBytesPerSec;

在这些类中,磁盘"和网络"两者合计. (同样,对于原始数据"忽略每秒"部分,它将提供越来越多的数据总量.)

In these classes, both Disk and Network are combined in the totals. (Again, for the "raw data" ignore the "per sec" part, it will give increasing total amounts of data).

我不认为Windows会按进程跟踪磁盘与网络IO的差异.

I do not think Windows keeps track of the difference in Disk vs. Network IO on a per-process basis.

您应采取的步骤:

  1. 使用所需的WMI字段名称定义逗号分隔的字符串

  1. Define a comma-separated string with the WMI field names you want

定义一个ValueType数组,其类型与字段名称匹配,在 相同的顺序

Define a ValueType array with types matching the field names, in the same order

执行Map<String, List<Object>> procs = WmiUtil.selectObjectsFrom(null, "Win32_PerfRawData_PerfProc_Process", processProperties, String.format("WHERE IdProcess=%d", pid), processPropertyTypes);

使用procs.get("FieldNameHere").get(0)

这篇关于Java(Windows)-通过进程ID,获取内存使用情况,磁盘使用情况,网络使用情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆