前言
我之前一篇文章:
【原创】Java获取CPU占用率、内存占用率最简单的方式_java获取cpu使用率-CSDN博客
这篇文章虽然简单,但是只能针对JDK8,换成现在模块化的JDK后,OperatingSystemMXBean类就无法反射获取其中的信息了,会导致FastJson报错。当然我已经找到了解决方法。
直接上代码
package com.itdct.justtest.test.monitor;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.text.DecimalFormat;import lombok.extern.slf4j.Slf4j;/*** @author DCTANT* @version 1.0* @date 2024/3/21 11:21:21* @description*/
@Slf4j
public class MonitorServer {private static final long GB = 1024 * 1024 * 1024;private static final long MB = 1024 * 1024;private static final DecimalFormat decimalFormat = new DecimalFormat("0.0");public MonitorInfoModel monitor() {MonitorInfoModel monitorInfoModel = new MonitorInfoModel();MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();long usedHeapMemory = heapMemoryUsage.getUsed();long maxHeapMemory = heapMemoryUsage.getMax();long usedNonHeapMemory = nonHeapMemoryUsage.getUsed();long maxNonHeapMemory = nonHeapMemoryUsage.getMax();String usedHeapMemoryInfo = decimalFormat.format(1.0 * usedHeapMemory / MB) + "MB";String maxHeapMemoryInfo = decimalFormat.format(1.0 * maxHeapMemory / MB) + "MB";String usedNonHeapMemoryInfo = decimalFormat.format(1.0 * usedNonHeapMemory / MB) + "MB";String maxNonHeapMemoryInfo;if (maxNonHeapMemory == -1L) {maxNonHeapMemoryInfo = "-";} else {maxNonHeapMemoryInfo = decimalFormat.format(1.0 * maxNonHeapMemory / MB) + "MB";}monitorInfoModel.setUsedHeapMemoryInfo(usedHeapMemoryInfo);monitorInfoModel.setMaxHeapMemoryInfo(maxHeapMemoryInfo);monitorInfoModel.setUsedNonHeapMemoryInfo(usedNonHeapMemoryInfo);monitorInfoModel.setMaxNonHeapMemoryInfo(maxNonHeapMemoryInfo);OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {com.sun.management.OperatingSystemMXBean opBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;double cpuLoad = opBean.getCpuLoad();String cpuLoadInfo = decimalFormat.format(cpuLoad * 100) + "%";monitorInfoModel.setCpuLoadInfo(cpuLoadInfo);double processCpuLoad = opBean.getProcessCpuLoad();String processCpuLoadInfo = decimalFormat.format(processCpuLoad * 100) + "%";monitorInfoModel.setProcessCpuLoadInfo(processCpuLoadInfo);long totalMemorySize = opBean.getTotalMemorySize();long freeMemorySize = opBean.getFreeMemorySize();String totalMemoryInfo = decimalFormat.format(1.0 * totalMemorySize / GB) + "GB";String freeMemoryInfo = decimalFormat.format(1.0 * freeMemorySize / GB) + "GB";String useMemoryInfo = decimalFormat.format(1.0 * (totalMemorySize - freeMemorySize) / GB) + "GB";String memoryUseRatioInfo = decimalFormat.format((1.0 * (totalMemorySize - freeMemorySize) / totalMemorySize * 100)) + "%";monitorInfoModel.setTotalMemoryInfo(totalMemoryInfo);monitorInfoModel.setFreeMemoryInfo(freeMemoryInfo);monitorInfoModel.setUseMemoryInfo(useMemoryInfo);monitorInfoModel.setMemoryUseRatioInfo(memoryUseRatioInfo);long freeSwapSpaceSize = opBean.getFreeSwapSpaceSize();long totalSwapSpaceSize = opBean.getTotalSwapSpaceSize();String freeSwapSpaceInfo = decimalFormat.format(1.0 * freeSwapSpaceSize / GB) + "GB";String totalSwapSpaceInfo = decimalFormat.format(1.0 * totalSwapSpaceSize / GB) + "GB";String useSwapSpaceInfo = decimalFormat.format(1.0 * (totalSwapSpaceSize - freeSwapSpaceSize) / GB) + "GB";String swapUseRatioInfo = decimalFormat.format((1.0 * (totalSwapSpaceSize - freeSwapSpaceSize) / totalSwapSpaceSize * 100)) + "%";monitorInfoModel.setFreeSwapSpaceInfo(freeSwapSpaceInfo);monitorInfoModel.setTotalSwapSpaceInfo(totalSwapSpaceInfo);monitorInfoModel.setUseSwapSpaceInfo(useSwapSpaceInfo);monitorInfoModel.setSwapUseRatioInfo(swapUseRatioInfo);String arch = opBean.getArch();String name = opBean.getName();monitorInfoModel.setArch(arch);monitorInfoModel.setName(name);}return monitorInfoModel;}public static void main(String[] args) throws InterruptedException {MonitorServer monitorServer = new MonitorServer();while (true) {MonitorInfoModel infoModel = monitorServer.monitor();
// String jsonString = JSON.toJSONString(infoModel, SerializerFeature.PrettyFormat);
// log.info(jsonString);log.info("""堆内存使用情况:使用中的堆内存:{}最大堆内存:{}使用中的非堆内存:{}最大非堆内存:{}""",infoModel.getUsedHeapMemoryInfo(),infoModel.getMaxHeapMemoryInfo(),infoModel.getUsedNonHeapMemoryInfo(),infoModel.getMaxNonHeapMemoryInfo());log.info("""系统信息:系统架构:{}系统名称:{}系统使用情况:CPU使用率:{}JVM进程CPU使用率:{}系统总内存:{}使用中的内存:{}内存使用率:{}系统总交换内存:{}使用中的交换内存:{}交换内存使用率:{}""",infoModel.getArch(),infoModel.getName(),infoModel.getCpuLoadInfo(),infoModel.getProcessCpuLoadInfo(),infoModel.getTotalMemoryInfo(),infoModel.getUseMemoryInfo(),infoModel.getMemoryUseRatioInfo(),infoModel.getTotalSwapSpaceInfo(),infoModel.getUseSwapSpaceInfo(),infoModel.getSwapUseRatioInfo());Thread.sleep(1000);}}
}
核心代码自然是这句:
if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {com.sun.management.OperatingSystemMXBean opBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;
将java.lang.management.OperatingSystemMXBean转为com.sun.management.OperatingSystemMXBean,即可获取系统运行信息
其中MonitorInfoModel类为:
package com.itdct.justtest.test.monitor;import lombok.Data;/*** @author DCTANT* @version 1.0* @date 2024/3/21 11:21:36* @description*/
@Data
public class MonitorInfoModel {// INFO: DCTANT: 2024/3/21 JVM堆信息/*** 使用中的堆内存信息*/private String usedHeapMemoryInfo;/*** 最大堆内存信息*/private String maxHeapMemoryInfo;/*** 使用中的非堆内存信息*/private String usedNonHeapMemoryInfo;/*** 最大非堆内存信息*/private String maxNonHeapMemoryInfo;// INFO: DCTANT: 2024/3/21 计算机信息/*** 系统cpu使用率信息*/private String cpuLoadInfo;/*** JVM进程 cpu使用率信息*/private String processCpuLoadInfo;/*** 系统总内存信息*/private String totalMemoryInfo;/*** 系统空闲内存信息*/private String freeMemoryInfo ;/*** 使用中的内存信息*/private String useMemoryInfo ;/*** 内存使用率*/private String memoryUseRatioInfo;/*** 空闲交换内存信息*/private String freeSwapSpaceInfo;/*** 总交换内存信息*/private String totalSwapSpaceInfo;/*** 使用中交换内存信息*/private String useSwapSpaceInfo;/*** 交换内存使用率信息*/private String swapUseRatioInfo;/*** 系统架构*/private String arch;/*** 系统名称*/private String name;}
封装之后返回,直接就能使用,非常优雅