java程序獲取windows內存佔用|CPU使用率|啓動命令|進程ID|進程名稱

java程序獲取windows內存佔用(MB)|CPU使用率|啓動命令|進程ID|進程名稱

public class App {
    // 可以設置長些,防止讀到運行此次系統檢查時的cpu佔用率,就不準了
    private static final int CPUTIME = 5000;

    private static final int MB = 1024 * 1024;

    public static void main(String[] args) throws IOException, InterruptedException {

//        Thread.sleep(30000);

        MonitorInfoBean monitorInfo = getMonitorInfoBean();
        List<PerfRawData> perfRawDataList = getCpuUsage();
        List<ProcessCmdLine> processCmdLineList = getProcessCmdLineList();
        for (MonitorInfoBean.ProcessDetail processDetail : monitorInfo.getProcessDetailList()) {
            PerfRawData perfRawData = perfRawDataList.stream().filter(d -> d.getPid() == processDetail.getPid()).findFirst().orElse(null);
            if (perfRawData == null) {
                processDetail.setCpuRatio(0);
            } else {
                processDetail.setCpuRatio(perfRawData.getCpuRatio());
            }
            ProcessCmdLine processCmdLine = processCmdLineList.stream().filter(d -> d.getPid() == processDetail.getPid()).findFirst().orElse(null);
            if (processCmdLine != null) {
                processDetail.setCmdLine(processCmdLine.getCmdLine());
            }
        }
        monitorInfo.getProcessDetailList().sort(Comparator.comparing(MonitorInfoBean.ProcessDetail::getCpuRatio).reversed());
        System.out.println("時間|進程ID|進程名稱|內存佔用(MB)|CPU使用率|啓動命令");
        for (MonitorInfoBean.ProcessDetail processDetail : monitorInfo.getProcessDetailList()) {
            System.out.println(String.format("%s|%s|%s|%s|%s|%s"
                    , DateFormat.getDateTimeInstance().format(processDetail.time)
                    , processDetail.pid
                    , processDetail.pName
                    , processDetail.memUsage / 1024
                    , new DecimalFormat("######0.00").format(processDetail.cpuRatio)
                    , processDetail.cmdLine));
        }
    }


    /**
     * 獲得當前的監控對象
     */
    private static MonitorInfoBean getMonitorInfoBean() throws IOException {

        OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

        MonitorInfoBean infoBean = new MonitorInfoBean();
        infoBean.setOsName(System.getProperty("os.name"));
        infoBean.setTotalMemorySize(operatingSystemMXBean.getTotalPhysicalMemorySize() / MB);
        infoBean.setFreePhysicalMemorySize(operatingSystemMXBean.getFreePhysicalMemorySize() / MB);
        infoBean.setUsedMemory(infoBean.getTotalMemorySize() - infoBean.getFreePhysicalMemorySize());

        List<String> cmdResult = execCmd("cmd.exe /c tasklist");

        List<MonitorInfoBean.ProcessDetail> processDetailList = new ArrayList<>();
        String line;
        for (int i = 0; i < cmdResult.size(); i++) {
            if (i <= 2 || StringUtils.isEmpty(cmdResult.get(i))) {
                continue;
            }
            line = cmdResult.get(i);
            if (line.length() > 0) {
                MonitorInfoBean.ProcessDetail processDetail = new MonitorInfoBean.ProcessDetail();
                processDetail.setTime(new Date());
                processDetail.setPName(line.substring(0, 29).trim());
                line = line.substring(29).trim();
                line = line.replaceAll("\\s+", " ");
                String[] lineArr = line.split(" ");
                processDetail.setPid(Integer.parseInt(lineArr[0]));
                processDetail.setMemUsage(Integer.parseInt(lineArr[3].replaceAll(",", "")));

                processDetailList.add(processDetail);
            }
        }
        infoBean.setProcessDetailList(processDetailList);
        return infoBean;
    }

    /**
     * 計算CPU使用率
     */
    private static List<PerfRawData> getCpuUsage() throws IOException, InterruptedException {
        List<PerfRawData> perfRawDataList1 = getPerfRawDataList();
        Thread.sleep(CPUTIME);
        List<PerfRawData> perfRawDataList2 = getPerfRawDataList();

        for (PerfRawData perfRawData1 : perfRawDataList1) {
            PerfRawData perfRawData2 = perfRawDataList2.stream().filter(d -> d.getPid() == perfRawData1.getPid()).findFirst().orElse(null);
            if (perfRawData2 == null) {
                perfRawData1.setCpuRatio(0);
                continue;
            }
            long n1 = perfRawData1.getPercentProcessorTime();
            long n2 = perfRawData2.getPercentProcessorTime();
            long d1 = perfRawData1.getTimestamp_Sys100NS();
            long d2 = perfRawData2.getTimestamp_Sys100NS();
            perfRawData1.setCpuRatio(((double) (n2 - n1) / (d2 - d1)) * 100);
        }

        return perfRawDataList1;
    }

    private static List<PerfRawData> getPerfRawDataList() throws IOException {
        List<PerfRawData> perfRawDataList = new ArrayList<>();
        String command = "powershell.exe  Get-WmiObject -Class Win32_PerfRawData_PerfProc_Process IDProcess,Name,PercentProcessorTime,TimeStamp_Sys100NS";

        List<String> cmdResult = execCmd(command);
        PerfRawData perfRawData = new PerfRawData();
        for (String s : cmdResult) {
            if (StringUtils.isEmpty(s)) {
                if (perfRawData.getPid() > 0) {
                    perfRawDataList.add(perfRawData);
                    perfRawData = new PerfRawData();
                }
                continue;
            }
            String[] sArr = s.split(":");
            if (s.contains("IDProcess")) {
                perfRawData.setPid(Integer.parseInt(sArr[1].trim()));
            } else if (s.contains("Name                 :")) {
                perfRawData.setPName(sArr[1].trim());
            } else if (s.contains("PercentProcessorTime")) {
                perfRawData.setPercentProcessorTime(Long.parseLong(sArr[1].trim()));
            } else if (s.contains("Timestamp_Sys100NS")) {
                perfRawData.setTimestamp_Sys100NS(Long.parseLong(sArr[1].trim()));
            }
        }

        return perfRawDataList;
    }

    private static List<ProcessCmdLine> getProcessCmdLineList() throws IOException {
        List<ProcessCmdLine> processCmdLineList = new ArrayList<>();
        String command = "powershell.exe wmic process get processID,caption,commandline /value";

        List<String> cmdResult = execCmd(command);
        ProcessCmdLine processCmdLine = new ProcessCmdLine();
        for (String s : cmdResult) {
            if (StringUtils.isEmpty(s)) {
                if (processCmdLine.getPid() > 0 && StringUtils.hasText(processCmdLine.getCmdLine())) {
                    processCmdLineList.add(processCmdLine);
                    processCmdLine = new ProcessCmdLine();
                }
                continue;
            }
            String[] sArr = s.split("=");
            if (s.contains("CommandLine")) {
                processCmdLine.setCmdLine(sArr.length == 2 ? sArr[1].trim() : "empty");
            } else if (s.contains("ProcessId")) {
                processCmdLine.setPid(Integer.parseInt(sArr[1].trim()));
            }
        }

        return processCmdLineList;
    }

    /**
     * 執行cmd命令,按行返回執行結果
     *
     * @param command cmd命令
     * @return 按行返回執行結果
     * @throws IOException
     */
    private static List<String> execCmd(String command) throws IOException {
        Process powerShellProcess = Runtime.getRuntime().exec(command);
        powerShellProcess.getOutputStream().close();
        List<String> lineList = new ArrayList<>();
        String line;
        BufferedReader stdout = new BufferedReader(new InputStreamReader(powerShellProcess.getInputStream()));
        while ((line = stdout.readLine()) != null) {
            lineList.add(line);
        }
        stdout.close();
        return lineList;
    }

    @Data
    public static class MonitorInfoBean {
        // 操作系統(MB)
        private String osName;
        // 總的物理內存(MB)
        private long totalMemorySize;
        // 剩餘的物理內存(MB)
        private long freePhysicalMemorySize;
        // 已使用的物理內存(MB)
        private long usedMemory;

        private List<ProcessDetail> processDetailList;

        @Data
        public static class ProcessDetail {
            private Date time;
            private String pName;
            private int pid;
            // 佔用內存(KB)
            private int memUsage;
            // CPU使用率(百分比)
            private double cpuRatio;
            private String cmdLine;
        }
    }

    @Data
    public static class PerfRawData {
        private int pid;
        private String pName;
        private long PercentProcessorTime;
        private long Timestamp_Sys100NS;
        /**
         * CPU使用率百分比*100
         */
        private double cpuRatio;
    }

    @Data
    public static class ProcessCmdLine {
        private int pid;
        private String cmdLine;

    }
}

打印結果爲:

時間|進程ID|進程名稱|內存佔用(MB)|CPU使用率|啓動命令
2021-7-13 17:48:50|14752|java.exe|30|8.93|empty
2021-7-13 17:48:50|4472|Memory Compression|1218|4.36|empty
2021-7-13 17:48:50|12164|idea64.exe|2569|3.57|"D:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin\idea64.exe"
2021-7-13 17:48:50|2296|ekrn.exe|146|2.18|empty
2021-7-13 17:48:50|4|System|0|1.79|empty
2021-7-13 17:48:50|6176|softmon.exe|8|1.59|empty
2021-7-13 17:48:50|6940|svchost.exe|24|1.39|C:\Windows\system32\svchost.exe -k UnistackSvcGroup
2021-7-13 17:48:50|1248|dwm.exe|150|1.19|empty
2021-7-13 17:48:50|792|csrss.exe|5|0.99|empty
2021-7-13 17:48:50|7136|WmiPrvSE.exe|21|0.60|empty
2021-7-13 17:48:50|564|svchost.exe|23|0.40|empty
2021-7-13 17:48:50|5796|tmcsvc.exe|6|0.40|empty
2021-7-13 17:48:50|6700|CGESA.exe|9|0.40|empty
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章