2015年3月28日 星期六

[Java]在windows上透過wmic取得CPU使用率

程式來源
http://puremonkey2010.blogspot.tw/2011/05/java-cpu.html
資料來源
http://forum.slime.com.tw/thread61654.html

WMIC,英文全稱Windows Management Instrumentation Command-line,即Windows管理規範指令行。並聲稱使用WMIC,再配合其他現存的指令行工具,管理員幾乎可以完成所有的管理工作,而不必再過多地依賴那些圖形界面。最重要的是wmic可以支援格式化輸出。

具體來說,你可以使用WMIC實現如下的管理工作:

  1、本機電腦管理

  2、遠端單個電腦管理

  3、遠端多個電腦管理

  4、使用遠端會話的電腦管理(如Telnet)

  5、使用管理指令碼的自動管理


wmic使用範例可以參考這一篇
http://www.dotblogs.com.tw/dc690216/archive/2011/08/13/33059.aspx


程式碼共有如下五個

 
/*
 裝載監控的信息Bean
 */
package cpu_use;

/**
 *
 * @author bert
 */
public class MonitorInfoBean {
    /** 可使用內存. */  
    private long totalMemory;  
  
    /** */  
    /** 剩餘內存. */  
    private long freeMemory;  
  
    /** */  
    /** 最大可使用內存. */  
    private long maxMemory;  
  
    /** */  
    /** 操作系統. */  
    private String osName;  
  
    /** */  
    /** 總物理內存. */  
    private long totalMemorySize;  
  
    /** */  
    /** 剩餘的物理內存. */  
    private long freePhysicalMemorySize;  
  
    /** */  
    /** 已使用的物理內存. */  
    private long usedMemory;  
  
    /** */  
    /** 線程總數. */  
    private int totalThread;  
  
    /** */  
    /** cpu使用率. */  
    private double cpuRatio;  
  
    public long getFreeMemory() {  
        return freeMemory;  
    }  
  
    public void setFreeMemory(long freeMemory) {  
        this.freeMemory = freeMemory;  
    }  
  
    public long getFreePhysicalMemorySize() {  
        return freePhysicalMemorySize;  
    }  
  
    public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {  
        this.freePhysicalMemorySize = freePhysicalMemorySize;  
    }  
  
    public long getMaxMemory() {  
        return maxMemory;  
    }  
  
    public void setMaxMemory(long maxMemory) {  
        this.maxMemory = maxMemory;  
    }  
  
    public String getOsName() {  
        return osName;  
    }  
  
    public void setOsName(String osName) {  
        this.osName = osName;  
    }  
  
    public long getTotalMemory() {  
        return totalMemory;  
    }  
  
    public void setTotalMemory(long totalMemory) {  
        this.totalMemory = totalMemory;  
    }  
  
    public long getTotalMemorySize() {  
        return totalMemorySize;  
    }  
  
    public void setTotalMemorySize(long totalMemorySize) {  
        this.totalMemorySize = totalMemorySize;  
    }  
  
    public int getTotalThread() {  
        return totalThread;  
    }  
  
    public void setTotalThread(int totalThread) {  
        this.totalThread = totalThread;  
    }  
  
    public long getUsedMemory() {  
        return usedMemory;  
    }  
  
    public void setUsedMemory(long usedMemory) {  
        this.usedMemory = usedMemory;  
    }  
  
    public double getCpuRatio() {  
        return cpuRatio;  
    }  
  
    public void setCpuRatio(double cpuRatio) {  
        this.cpuRatio = cpuRatio;  
    }  
}


 
/*
提供解耦合的介面
 */
package cpu_use;

/**
 *
 * @author bert
 */
public interface IMonitorService {
      /** *//** 
     * 獲得當前監控對像. 
     * @return 返回監測對象 
     * @throws Exception 
     */  
    public MonitorInfoBean getMonitorInfoBean() throws Exception;  
}


 
/*
獲取系統訊息的實作類別
 */
package cpu_use;

import java.io.InputStreamReader;  
import java.io.LineNumberReader;  
//import sun.management.ManagementFactory;  
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean; 

public class MonitorServiceImpl implements IMonitorService
{
    public  static final int CPUTIME = 5000;  
    private static final int PERCENT = 100;  
    private static final int FAULTLENGTH = 10;  
    private static String PROC_CMD = System.getenv("windir")  
                                    + "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"  
                                    + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";  
    private long[] initCpuInfo = null;  
      
    public MonitorServiceImpl(){  
        try{  
            initCpuInfo = readCpu(Runtime.getRuntime().exec(PROC_CMD));  
        }catch(Exception e){  
            e.printStackTrace();  
            initCpuInfo = null;  
        }  
    }  
      
    @Override  
    public MonitorInfoBean getMonitorInfoBean() throws Exception {  
        int kb = 1024;  
          
        // 可使用內存  
        long totalMemory = Runtime.getRuntime().totalMemory() / kb;  
        // 剩餘內存  
        long freeMemory = Runtime.getRuntime().freeMemory() / kb;  
        // 最大可使用內存  
        long maxMemory = Runtime.getRuntime().maxMemory() / kb;  
  
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory  
                .getOperatingSystemMXBean();  
  
        // 操作系統  
        String osName = System.getProperty("os.name");  
        // 總物理內存  
        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;  
        // 剩餘的物理內存  
        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;  
        // 已使用的物理內存  
        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb  
                .getFreePhysicalMemorySize())  
                / kb;  
  
        // 獲得線程總數  
        ThreadGroup parentThread;  
        for (parentThread = Thread.currentThread().getThreadGroup(); parentThread  
                .getParent() != null; parentThread = parentThread.getParent())  
            ;  
        int totalThread = parentThread.activeCount();  
  
        double cpuRatio = 0;  
        if (osName.toLowerCase().startsWith("windows")) {             
            cpuRatio = this.getCpuRatioForWindows();  
        }  
          
        // 返回對象  
        MonitorInfoBean infoBean = new MonitorInfoBean();  
        infoBean.setFreeMemory(freeMemory);  
        infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize);  
        infoBean.setMaxMemory(maxMemory);  
        infoBean.setOsName(osName);  
        infoBean.setTotalMemory(totalMemory);  
        infoBean.setTotalMemorySize(totalMemorySize);  
        infoBean.setTotalThread(totalThread);  
        infoBean.setUsedMemory(usedMemory);  
        infoBean.setCpuRatio(cpuRatio);  
        return infoBean;  
    }  
      
    private double getCpuRatioForWindows() {  
        try {  
            if(initCpuInfo==null) return 0.0;  
            // 取得進程信息  
            //long[] c0 = readCpu(Runtime.getRuntime().exec(PROC_CMD));  
            //Thread.sleep(CPUTIME);  
            long[] c1 = readCpu(Runtime.getRuntime().exec(PROC_CMD));  
            if (c1 != null) {  
                long idletime = c1[0] - initCpuInfo[0];  
                long busytime = c1[1] - initCpuInfo[1];  
                return Double.valueOf(  
                        PERCENT * (busytime) / (busytime + idletime))  
                        .doubleValue();  
            } else {  
                return 0.0;  
            }  
        } catch (Exception ex) {  
            ex.printStackTrace();  
            return 0.0;  
        }  
    }  
      
    private long[] readCpu(final Process proc) {  
        long[] retn = new long[2];  
        try {  
            proc.getOutputStream().close();  
            InputStreamReader ir = new InputStreamReader(proc.getInputStream());  
            LineNumberReader input = new LineNumberReader(ir);  
            String line = input.readLine();  
            if (line == null || line.length() < FAULTLENGTH) {  
                return null;  
            }  
            int capidx = line.indexOf("Caption");  
            int cmdidx = line.indexOf("CommandLine");  
            int rocidx = line.indexOf("ReadOperationCount");  
            int umtidx = line.indexOf("UserModeTime");  
            int kmtidx = line.indexOf("KernelModeTime");  
            int wocidx = line.indexOf("WriteOperationCount");  
            long idletime = 0;  
            long kneltime = 0;  
            long usertime = 0;  
            while ((line = input.readLine()) != null) {  
                if (line.length() < wocidx) {  
                    continue;  
                }  
                // 字段出現順序:Caption,CommandLine,KernelModeTime,ReadOperationCount,  
                // ThreadCount,UserModeTime,WriteOperation  
                String caption = Bytes.substring(line, capidx, cmdidx - 1).trim();  
                String cmd = Bytes.substring(line, cmdidx, kmtidx - 1).trim();  
                if (cmd.indexOf("wmic.exe") >= 0) {  
                    continue;  
                }  
                // log.info("line="+line);  
                if (caption.equals("System Idle Process")  
                        || caption.equals("System")) {  
                    idletime += Long.valueOf(  
                            Bytes.substring(line, kmtidx, rocidx - 1).trim())  
                            .longValue();  
                    idletime += Long.valueOf(  
                            Bytes.substring(line, umtidx, wocidx - 1).trim())  
                            .longValue();  
                    continue;  
                }  
  
                kneltime += Long.valueOf(  
                        Bytes.substring(line, kmtidx, rocidx - 1).trim())  
                        .longValue();  
                usertime += Long.valueOf(  
                        Bytes.substring(line, umtidx, wocidx - 1).trim())  
                        .longValue();  
            }  
            retn[0] = idletime;  
            retn[1] = kneltime + usertime;  
            return retn;  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        } finally {  
            try {  
                proc.getInputStream().close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
    
}


 
/*
解決 String.subString() 處理中文的問題 (將中文試為一個byte)
 */
package cpu_use;

/**
 *
 * @author bert
 */
public class Bytes {
     public static String substring(String src, int start_idx, int end_idx){  
        byte[] b = src.getBytes();  
        String tgt = "";  
        for(int i=start_idx; i<=end_idx; i++){  
            tgt +=(char)b[i];  
        }  
        return tgt;  
    }
}


 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cpu_use;

/**
 *
 * @author bert
 */
public class CPU_Useage {
     public static void main(String args[])  
    {  
        MonitorServiceImpl MSImpl = new MonitorServiceImpl();  
        try {  
            Thread.sleep(MonitorServiceImpl.CPUTIME);  
            MonitorInfoBean bean = MSImpl.getMonitorInfoBean();  
            System.out.println("系統: "+bean.getOsName());  
            System.out.println("CPU使用率: "+bean.getCpuRatio()+"%");  
            System.out.println("JVM可使用記憶體: "+String.valueOf(bean.getTotalMemory()/1000.0)+" MB");  
            System.out.println("JVM尚餘記憶體: "+bean.getFreeMemory()/1000.0+" MB");  
            System.out.println("JVM最大可配置記憶體: "+bean.getMaxMemory()/1000.0+" MB");  
            System.out.println("============================");  
            System.out.println("實體記憶體: "+bean.getTotalMemorySize()/1000.0+" MB");  
            System.out.println("實體記憶體可用: "+bean.getFreePhysicalMemorySize()/1000.0+" MB");  
            System.out.println("已使用實體記憶體: "+bean.getUsedMemory()/1000.0+" MB");  
            System.out.println("============================");  
            System.out.println("Total Thread in Java: "+bean.getTotalThread());  
        } catch (Exception e) {           
            e.printStackTrace();  
        }
    }  
}


執行後如下

沒有留言:

張貼留言