OSHI可以获取系统信息(CPU、内存、磁盘、网络等),纯Java实现(通过JNA访问本地API,无需安装本地库),跨平台支持。
引入依赖
XML
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.6.5</version>
</dependency>
编写测试用例
java
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
@Slf4j
public class ResourceMonitorTest {
@Test
public void testGetResource() {
// 获取系统信息
SystemInfo si = new SystemInfo();
// 获取硬件抽象层
HardwareAbstractionLayer hardware = si.getHardware();
log.info("===============================CPU信息===============================");
CentralProcessor processor = hardware.getProcessor();
CentralProcessor.ProcessorIdentifier processorIdentifier = processor.getProcessorIdentifier();
String processorName = processorIdentifier.getName();
log.info("CPU 名称: {}", processorName);
String vendor = processorIdentifier.getVendor();
log.info("CPU 供应商: {}", vendor);
long cpuFreq = processorIdentifier.getVendorFreq();
log.info("CPU 频率: {}", cpuFreq);
int logicalProcessorCount = processor.getLogicalProcessorCount();
log.info("CPU 核心数: {}", logicalProcessorCount);
int physicalProcessorCount = processor.getPhysicalProcessorCount();
log.info("CPU 物理核心数: {}", physicalProcessorCount);
// CPU 负载 (最近1/5/15分钟)
double[] loadAverage = processor.getSystemLoadAverage(3);
log.info("CPU 负载: {}", loadAverage[0]);
log.info("===============================实时 CPU 使用率===============================");
// 第一次调用获取 ticks
long[] prevTicks = processor.getSystemCpuLoadTicks();
// 等待1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 第二次调用计算使用率
long[] ticks = processor.getSystemCpuLoadTicks();
long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
log.info("应用程序CPU使用率:{}", user);
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
log.info("应用程序优先CPU使用率:{}", nice);
long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
log.info("系统程序CPU使用率:{}", sys);
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
log.info("CPU空闲时间:{}", idle);
long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
log.info("CPU等待率:{}", iowait);
long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
log.info("CPU中断率:{}", irq);
long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
log.info("CPU软中断率:{}", softirq);
long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
log.info("CPU抢占率:{}", steal);
long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal;
log.info("CPU总使用率:{}", totalCpu);
// 计算各状态百分比
double cpuUsage = 100d * (totalCpu - idle) / totalCpu;
log.info("CPU使用率:{}", cpuUsage);
double ioWaitPercent = 100d * iowait / totalCpu;
log.info("IO等待使用率:{}", ioWaitPercent);
log.info("===============================内存信息===============================");
GlobalMemory memory = hardware.getMemory();
double gbNum = 1024.0 * 1024.0 * 1024.0;
// 总内存 (bytes)
long totalMemory = memory.getTotal();
BigDecimal totalMemoryDec = new BigDecimal(totalMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("总内存:{}GB", totalMemoryDec);
// 可用内存 (bytes)
long availableMemory = memory.getAvailable();
BigDecimal availableMemoryDec = new BigDecimal(availableMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("可用内存:{}GB", availableMemoryDec);
// 已用内存 (bytes)
long usedMemory = totalMemory - availableMemory;
BigDecimal usedMemoryDec = new BigDecimal(usedMemory / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("已用内存:{}GB", usedMemoryDec);
// 交换空间信息
long totalSwap = memory.getVirtualMemory().getSwapTotal();
BigDecimal totalSwapDec = new BigDecimal(totalSwap / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("总交换空间:{}GB", totalSwapDec);
long usedSwap = memory.getVirtualMemory().getSwapUsed();
BigDecimal usedSwapDec = new BigDecimal(usedSwap / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("已用交换空间:{}GB", usedSwapDec);
// 内存使用率
double memoryUsagePercent = 100d * usedMemory / totalMemory;
BigDecimal memoryUsagePercentDec = new BigDecimal(memoryUsagePercent / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("内存使用率:{}%", memoryUsagePercentDec);
log.info("===============================磁盘设备信息===============================");
List<HWDiskStore> diskStores = hardware.getDiskStores();
for (HWDiskStore disk : diskStores) {
String name = disk.getName();
String model = disk.getModel();
log.info("磁盘:{},磁盘型号:{}", name, model);
long size = disk.getSize();
BigDecimal sizeDec = new BigDecimal(size / gbNum).setScale(2, RoundingMode.HALF_UP);
log.info("磁盘:{},磁盘大小:{}GB", name, sizeDec);
long reads = disk.getReads();
log.info("磁盘:{},读取次数:{}", name, reads);
long readBytes = disk.getReadBytes();
log.info("磁盘:{},读取字节数:{}", name, readBytes);
long writes = disk.getWrites();
log.info("磁盘:{},写入次数:{}", name, writes);
long writeBytes = disk.getWriteBytes();
log.info("磁盘:{},写入字节数:{}", name, writeBytes);
long transferTime = disk.getTransferTime();
log.info("磁盘:{},传输时间:{}", name, transferTime);
}
log.info("===============================网络接口信息===============================");
List<NetworkIF> networkIFs = hardware.getNetworkIFs();
for (NetworkIF net : networkIFs) {
String name = net.getName();
String displayName = net.getDisplayName();
log.info("网络接口:{},显示名称:{}", name, displayName);
String mac = net.getMacaddr();
log.info("网络接口:{},MAC地址:{}", name, mac);
long mtu = net.getMTU();
log.info("网络接口:{},MTU值:{}", name, mtu);
long speed = net.getSpeed();
log.info("网络接口:{},网卡速度:{}", name, speed);
String[] ipv4 = net.getIPv4addr();
log.info("网络接口:{},IPv4 地址:{}", name, ipv4);
String[] ipv6 = net.getIPv6addr();
log.info("网络接口:{},IPv6 地址:{}", name, ipv6);
}
// 第一次获取数据
long bytesRecv = 0L;
long bytesSent = 0L;
for (NetworkIF net : networkIFs) {
net.updateAttributes();
bytesRecv = net.getBytesRecv();
bytesSent = net.getBytesSent();
long packetsRecv = net.getPacketsRecv();
long packetsSent = net.getPacketsSent();
}
// 等待1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 第二次获取并计算速率
for (NetworkIF net : networkIFs) {
net.updateAttributes();
long newRecv = net.getBytesRecv();
long newSent = net.getBytesSent();
// 计算每秒接收/发送的字节数
long recvRate = newRecv - bytesRecv;
long sentRate = newSent - bytesSent;
log.info("网卡 {} 接收 {} 字节/秒, 发送 {} 字节/秒", net.getName(), recvRate, sentRate);
}
log.info("===============================操作系统信息===============================");
OperatingSystem os = si.getOperatingSystem();
String family = os.getFamily();
log.info("操作系统 {}", family);
String manufacturer = os.getManufacturer();
log.info("操作系统制造商 {}", manufacturer);
OperatingSystem.OSVersionInfo versionInfo = os.getVersionInfo();
log.info("操作系统版本 {}", versionInfo.toString());
long uptime = os.getSystemUptime();
log.info("系统启动时间 {}", uptime);
int processCount = os.getProcessCount();
log.info("进程数量 {}", processCount);
int threadCount = os.getThreadCount();
log.info("线程数量 {}", threadCount);
OSProcess currentProcess = os.getProcess(os.getProcessId());
log.info("当前进程 {}", currentProcess.getName());
long processMemory = currentProcess.getResidentSetSize();
log.info("进程内存占用 {}", processMemory);
double processCpuLoad = currentProcess.getProcessCpuLoadBetweenTicks(currentProcess);
log.info("进程CPU使用率 {}", processCpuLoad);
}
}