Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
oshi.driver.windows.registry.ProcessPerformanceData Maven / Gradle / Ivy
/*
* Copyright 2020-2023 The OSHI Project Contributors
* SPDX-License-Identifier: MIT
*/
package oshi.driver.windows.registry;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sun.jna.platform.win32.WinBase;
import oshi.annotation.concurrent.Immutable;
import oshi.annotation.concurrent.ThreadSafe;
import oshi.driver.windows.perfmon.ProcessInformation;
import oshi.driver.windows.perfmon.ProcessInformation.ProcessPerformanceProperty;
import oshi.util.GlobalConfig;
import oshi.util.tuples.Pair;
import oshi.util.tuples.Triplet;
/**
* Utility to read process data from HKEY_PERFORMANCE_DATA information with backup from Performance Counters or WMI
*/
@ThreadSafe
public final class ProcessPerformanceData {
private static final String PROCESS = "Process";
private static final boolean PERFDATA = GlobalConfig.get(GlobalConfig.OSHI_OS_WINDOWS_HKEYPERFDATA, true);
private ProcessPerformanceData() {
}
/**
* Query the registry for process performance counters
*
* @param pids An optional collection of process IDs to filter the list to. May be null for no filtering.
* @return A map with Process ID as the key and a {@link PerfCounterBlock} object populated with performance counter
* information if successful, or null otherwise.
*/
public static Map buildProcessMapFromRegistry(Collection pids) {
// Grab the data from the registry.
Triplet>, Long, Long> processData = null;
if (PERFDATA) {
processData = HkeyPerformanceDataUtil.readPerfDataFromRegistry(PROCESS, ProcessPerformanceProperty.class);
}
if (processData == null) {
return null;
}
List> processInstanceMaps = processData.getA();
long now = processData.getC(); // 1970 epoch
// Create a map and fill it
Map processMap = new HashMap<>();
// Iterate instances.
for (Map processInstanceMap : processInstanceMaps) {
int pid = ((Integer) processInstanceMap.get(ProcessPerformanceProperty.IDPROCESS)).intValue();
String name = (String) processInstanceMap.get(ProcessPerformanceProperty.NAME);
if ((pids == null || pids.contains(pid)) && !"_Total".equals(name)) {
// Field name is elapsed time but the value is the process start time
long ctime = (Long) processInstanceMap.get(ProcessPerformanceProperty.ELAPSEDTIME);
// if creation time value is less than current millis, it's in 1970 epoch,
// otherwise it's 1601 epoch and we must convert
if (ctime > now) {
ctime = WinBase.FILETIME.filetimeToDate((int) (ctime >> 32), (int) (ctime & 0xffffffffL)).getTime();
}
long upTime = now - ctime;
if (upTime < 1L) {
upTime = 1L;
}
processMap.put(pid,
new PerfCounterBlock(name,
(Integer) processInstanceMap.get(ProcessPerformanceProperty.CREATINGPROCESSID),
(Integer) processInstanceMap.get(ProcessPerformanceProperty.PRIORITYBASE),
(Long) processInstanceMap.get(ProcessPerformanceProperty.PRIVATEBYTES), ctime, upTime,
(Long) processInstanceMap.get(ProcessPerformanceProperty.IOREADBYTESPERSEC),
(Long) processInstanceMap.get(ProcessPerformanceProperty.IOWRITEBYTESPERSEC),
(Integer) processInstanceMap.get(ProcessPerformanceProperty.PAGEFAULTSPERSEC)));
}
}
return processMap;
}
/**
* Query PerfMon for process performance counters
*
* @param pids An optional collection of process IDs to filter the list to. May be null for no filtering.
* @return A map with Process ID as the key and a {@link PerfCounterBlock} object populated with performance counter
* information.
*/
public static Map buildProcessMapFromPerfCounters(Collection pids) {
return buildProcessMapFromPerfCounters(pids, null);
}
/**
* Query PerfMon for process performance counters
*
* @param pids An optional collection of process IDs to filter the list to. May be null for no filtering.
* @param procName Filter by this process name.
* @return A map with Process ID as the key and a {@link PerfCounterBlock} object populated with performance counter
* information.
*/
public static Map buildProcessMapFromPerfCounters(Collection pids,
String procName) {
Map processMap = new HashMap<>();
Pair, Map>> instanceValues = ProcessInformation
.queryProcessCounters();
long now = System.currentTimeMillis(); // 1970 epoch
List instances = instanceValues.getA();
Map> valueMap = instanceValues.getB();
List pidList = valueMap.get(ProcessPerformanceProperty.IDPROCESS);
List ppidList = valueMap.get(ProcessPerformanceProperty.CREATINGPROCESSID);
List priorityList = valueMap.get(ProcessPerformanceProperty.PRIORITYBASE);
List ioReadList = valueMap.get(ProcessPerformanceProperty.IOREADBYTESPERSEC);
List ioWriteList = valueMap.get(ProcessPerformanceProperty.IOWRITEBYTESPERSEC);
List workingSetSizeList = valueMap.get(ProcessPerformanceProperty.PRIVATEBYTES);
List elapsedTimeList = valueMap.get(ProcessPerformanceProperty.ELAPSEDTIME);
List pageFaultsList = valueMap.get(ProcessPerformanceProperty.PAGEFAULTSPERSEC);
for (int inst = 0; inst < instances.size(); inst++) {
int pid = pidList.get(inst).intValue();
if (pids == null || pids.contains(pid)) {
// Field name is elapsed time but the value is the process start time
long ctime = elapsedTimeList.get(inst);
// if creation time value is less than current millis, it's in 1970 epoch,
// otherwise it's 1601 epoch and we must convert
if (ctime > now) {
ctime = WinBase.FILETIME.filetimeToDate((int) (ctime >> 32), (int) (ctime & 0xffffffffL)).getTime();
}
long upTime = now - ctime;
if (upTime < 1L) {
upTime = 1L;
}
processMap.put(pid,
new PerfCounterBlock(instances.get(inst), ppidList.get(inst).intValue(),
priorityList.get(inst).intValue(), workingSetSizeList.get(inst), ctime, upTime,
ioReadList.get(inst), ioWriteList.get(inst), pageFaultsList.get(inst).intValue()));
}
}
return processMap;
}
/**
* Class to encapsulate data from the registry performance counter block
*/
@Immutable
public static class PerfCounterBlock {
private final String name;
private final int parentProcessID;
private final int priority;
private final long residentSetSize;
private final long startTime;
private final long upTime;
private final long bytesRead;
private final long bytesWritten;
private final int pageFaults;
public PerfCounterBlock(String name, int parentProcessID, int priority, long residentSetSize, long startTime,
long upTime, long bytesRead, long bytesWritten, int pageFaults) {
this.name = name;
this.parentProcessID = parentProcessID;
this.priority = priority;
this.residentSetSize = residentSetSize;
this.startTime = startTime;
this.upTime = upTime;
this.bytesRead = bytesRead;
this.bytesWritten = bytesWritten;
this.pageFaults = pageFaults;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the parentProcessID
*/
public int getParentProcessID() {
return parentProcessID;
}
/**
* @return the priority
*/
public int getPriority() {
return priority;
}
/**
* @return the residentSetSize
*/
public long getResidentSetSize() {
return residentSetSize;
}
/**
* @return the startTime
*/
public long getStartTime() {
return startTime;
}
/**
* @return the upTime
*/
public long getUpTime() {
return upTime;
}
/**
* @return the bytesRead
*/
public long getBytesRead() {
return bytesRead;
}
/**
* @return the bytesWritten
*/
public long getBytesWritten() {
return bytesWritten;
}
/**
* @return the pageFaults
*/
public long getPageFaults() {
return pageFaults;
}
}
}