Java (Windows) - Ved proces id, få hukommelsesbrug, diskbrug, netbrug

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har undersøgt den bedste tilgang til at opnå følgende data for en bestemt proces:



  1. CPU-brug

  2. Hukommelsesforbrug

  3. Diskbrug

  4. Netværksforbrug



Jeg besluttede at gå med OSHI (Operating system &hardware information) API.
Uheldigvis for mig giver denne API ikke mig den ønskede information ud af kassen, det kræver nogle grundlæggende kendskab til, hvordan man kan beregne, for eksempel cpu-brugen pr. Proces.


Mit spørgsmål er: Hvordan kan jeg få hukommelsen, disken, netværksbrugen af ​​proces id?


ved hjælp af følgende eksempel på cpu-brugsdata pr. prcoess


For eksempel:


For at få den faktiske CPU brug af en claculator.exe kørende proces:


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


Rammen jeg bruger
https://github.com/oshi/oshi/tree/master/src/site/markdown
 viser den ønskede funktionalitet men mangler egnede eksempler [9]



  • Sprog: Java 8

  • Byg værktøj: Maven 2

  • OS: Windows 10 *



OSHI bibliotek + 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>

Bedste reference


Jeg er den, der gennemførte OSProcess-klassen i OSHI, som du refererer til, og har kommunikeret med dig i et problem på det pågældende projekt.


Mens OSHI i øjeblikket ikke leverer alle funktionaliteterne i OSProcess -grænsefladen, giver den dig adgangsmetoder til WMI-klasserne, som giver dig alle de oplysninger, du søger. Hvis du kigger på WindowsOperatingSystem-klassen, som implementerer den getProcess() -metode, du bruger, kan du kopiere/ændre koden ved hjælp af WMIUtil for direkte at hente de informationstyper, du har brug for. [10]


OSHI hentes for øjeblikket fra Win32\_Process WMI-klassen, men som jeg har nævnt i spørgsmålet, kan det være bedre at få oplysninger i stedet fra Win32\_PerfRawData\_PerfProc\_Process (som giver de rå data, du kan bruge til direkte beregninger) eller Win32\_PerfFormattedData\_PerfProc\_Process. I disse klasser kan du finde : [11] [12] [13]


CPU-brug



  • ElapsedTime

  • PercentPrivilegedTime

  • PercentProcessorTime

  • PercentUserTime



(Bemærk, mens navnet siger 'Procent', de rå data indeholder faktisk stigning 'flåter')


Hukommelsesbrug



  • VirtualBytes

  • WorkingSet



Diskbrug, Netværksforbrug



  • IOReadBytesPerSec;

  • IOWriteBytesPerSec;



I disse klasser kombineres både Disk og Netværk i totalen. (Igen, for 'rå data' ignorerer 'per sek' -delen, vil det give stigende samlede mængder data).


Jeg tror ikke, Windows holder styr på forskellen i Disk vs. Network IO på en per-proces basis.


Skridt du skal tage:



  1. Definer en kommasepareret streng med de ønskede WMI-feltnavne

  2. Definer en ValueType array med typer der matcher feltnavne, i
    den samme rækkefølge

  3. Udfør Map<String, List<Object>> procs = WmiUtil.selectObjectsFrom(null, "Win32\_PerfRawData\_PerfProc\_Process", processProperties, String.format("WHERE IdProcess=\%d", pid), processPropertyTypes);

  4. Hent hver værdi, du vil bruge procs.get("FieldNameHere").get(0)