java 获取系统信息及CPU的使用率

来源:互联网 发布:淘宝手机壳店铺装修 编辑:程序博客网 时间:2024/05/20 13:06

原文:http://kakaluyi.javaeye.com/blog/211492

最近做个项目,就是要取得cpu占有率等等的系统信息,一开始以为要用动态链接库了,但后来发现可以像下面这样做,不去调用jni,这样省去了很多看新技术的时间o(∩_∩)o...

在Java中,可以获得总的物理内存、剩余的物理内存、已使用的物理内存等信息,下面例子可以取得这些信息,并且获得在Windows下的内存使用率。
     首先编写一个MonitorInfoBean类,用来装载监控的一些信息,包括物理内存、剩余的物理内存、已使用的物理内存、内存使用率等字段,该类的代码如下:

Java代码 复制代码
  1. package com.amgkaka.performance;   
  2.   
  3. /** *//**  
  4.  * 监视信息的JavaBean类.  
  5.  * @author  amg  
  6.  * @version 1.0   
  7.  * Creation date: 2008-4-25 - 上午10:37:00  
  8.  */  
  9. public class MonitorInfoBean {   
  10.     /** *//** 可使用内存. */  
  11.     private long totalMemory;   
  12.        
  13.     /** *//** 剩余内存. */  
  14.     private long freeMemory;   
  15.        
  16.     /** *//** 最大可使用内存. */  
  17.     private long maxMemory;   
  18.        
  19.     /** *//** 操作系统. */  
  20.     private String osName;   
  21.        
  22.     /** *//** 总的物理内存. */  
  23.     private long totalMemorySize;   
  24.        
  25.     /** *//** 剩余的物理内存. */  
  26.     private long freePhysicalMemorySize;   
  27.        
  28.     /** *//** 已使用的物理内存. */  
  29.     private long usedMemory;   
  30.        
  31.     /** *//** 线程总数. */  
  32.     private int totalThread;   
  33.        
  34.     /** *//** cpu使用率. */  
  35.     private double cpuRatio;   
  36.   
  37.     public long getFreeMemory() {   
  38.         return freeMemory;   
  39.     }   
  40.   
  41.     public void setFreeMemory(long freeMemory) {   
  42.         this.freeMemory = freeMemory;   
  43.     }   
  44.   
  45.     public long getFreePhysicalMemorySize() {   
  46.         return freePhysicalMemorySize;   
  47.     }   
  48.   
  49.     public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {   
  50.         this.freePhysicalMemorySize = freePhysicalMemorySize;   
  51.     }   
  52.   
  53.     public long getMaxMemory() {   
  54.         return maxMemory;   
  55.     }   
  56.   
  57.     public void setMaxMemory(long maxMemory) {   
  58.         this.maxMemory = maxMemory;   
  59.     }   
  60.   
  61.     public String getOsName() {   
  62.         return osName;   
  63.     }   
  64.   
  65.     public void setOsName(String osName) {   
  66.         this.osName = osName;   
  67.     }   
  68.   
  69.     public long getTotalMemory() {   
  70.         return totalMemory;   
  71.     }   
  72.   
  73.     public void setTotalMemory(long totalMemory) {   
  74.         this.totalMemory = totalMemory;   
  75.     }   
  76.   
  77.     public long getTotalMemorySize() {   
  78.         return totalMemorySize;   
  79.     }   
  80.   
  81.     public void setTotalMemorySize(long totalMemorySize) {   
  82.         this.totalMemorySize = totalMemorySize;   
  83.     }   
  84.   
  85.     public int getTotalThread() {   
  86.         return totalThread;   
  87.     }   
  88.   
  89.     public void setTotalThread(int totalThread) {   
  90.         this.totalThread = totalThread;   
  91.     }   
  92.   
  93.     public long getUsedMemory() {   
  94.         return usedMemory;   
  95.     }   
  96.   
  97.     public void setUsedMemory(long usedMemory) {   
  98.         this.usedMemory = usedMemory;   
  99.     }   
  100.   
  101.     public double getCpuRatio() {   
  102.         return cpuRatio;   
  103.     }   
  104.   
  105.     public void setCpuRatio(double cpuRatio) {   
  106.         this.cpuRatio = cpuRatio;   
  107.     }   
  108. }  

 

接着编写一个获得当前的监控信息的接口,该类的代码如下所示:

Java代码 复制代码
  1. package com.amgkaka.performance;   
  2.   
  3. /** *//**  
  4.  * 获取系统信息的业务逻辑类接口.  
  5.  * @author amg * @version 1.0   
  6.  * Creation date: 2008-3-11 - 上午10:06:06  
  7.  */  
  8. public interface IMonitorService {   
  9.     /** *//**  
  10.      * 获得当前的监控对象.  
  11.      * @return 返回构造好的监控对象  
  12.      * @throws Exception  
  13.      * @author amgkaka  
  14.      * Creation date: 2008-4-25 - 上午10:45:08  
  15.      */  
  16.     public MonitorInfoBean getMonitorInfoBean() throws Exception;   
  17.   
  18. }  

  该类的实现类MonitorServiceImpl如下所示:

Java代码 复制代码
  1. package com.amgkaka.performance;   
  2.   
  3. import java.io.InputStreamReader;   
  4. import java.io.LineNumberReader;   
  5.   
  6. import sun.management.ManagementFactory;   
  7.   
  8. import com.sun.management.OperatingSystemMXBean;   
  9.   
  10. /** *//**  
  11.  * 获取系统信息的业务逻辑实现类.  
  12.  * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06  
  13.  */  
  14. public class MonitorServiceImpl implements IMonitorService {   
  15.     //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了   
  16.     private static final int CPUTIME = 5000;   
  17.   
  18.     private static final int PERCENT = 100;   
  19.   
  20.     private static final int FAULTLENGTH = 10;   
  21.   
  22.     /** *//**  
  23.      * 获得当前的监控对象.  
  24.      * @return 返回构造好的监控对象  
  25.      * @throws Exception  
  26.      * @author amg     * Creation date: 2008-4-25 - 上午10:45:08  
  27.      */  
  28.     public MonitorInfoBean getMonitorInfoBean() throws Exception {   
  29.         int kb = 1024;   
  30.            
  31.         // 可使用内存   
  32.         long totalMemory = Runtime.getRuntime().totalMemory() / kb;   
  33.         // 剩余内存   
  34.         long freeMemory = Runtime.getRuntime().freeMemory() / kb;   
  35.         // 最大可使用内存   
  36.         long maxMemory = Runtime.getRuntime().maxMemory() / kb;   
  37.   
  38.         OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory   
  39.                 .getOperatingSystemMXBean();   
  40.   
  41.         // 操作系统   
  42.         String osName = System.getProperty("os.name");   
  43.         // 总的物理内存   
  44.         long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;   
  45.         // 剩余的物理内存   
  46.         long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;   
  47.         // 已使用的物理内存   
  48.         long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb   
  49.                 .getFreePhysicalMemorySize())   
  50.                 / kb;   
  51.   
  52.         // 获得线程总数   
  53.         ThreadGroup parentThread;   
  54.         for (parentThread = Thread.currentThread().getThreadGroup(); parentThread   
  55.                 .getParent() != null; parentThread = parentThread.getParent())   
  56.             ;   
  57.         int totalThread = parentThread.activeCount();   
  58.   
  59.         double cpuRatio = 0;   
  60.         if (osName.toLowerCase().startsWith("windows")) {   
  61.             cpuRatio = this.getCpuRatioForWindows();   
  62.         }   
  63.            
  64.         // 构造返回对象   
  65.         MonitorInfoBean infoBean = new MonitorInfoBean();   
  66.         infoBean.setFreeMemory(freeMemory);   
  67.         infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize);   
  68.         infoBean.setMaxMemory(maxMemory);   
  69.         infoBean.setOsName(osName);   
  70.         infoBean.setTotalMemory(totalMemory);   
  71.         infoBean.setTotalMemorySize(totalMemorySize);   
  72.         infoBean.setTotalThread(totalThread);   
  73.         infoBean.setUsedMemory(usedMemory);   
  74.         infoBean.setCpuRatio(cpuRatio);   
  75.         return infoBean;   
  76.     }   
  77.   
  78.     /** *//**  
  79.      * 获得CPU使用率.  
  80.      * @return 返回cpu使用率  
  81.      * @author amg     * Creation date: 2008-4-25 - 下午06:05:11  
  82.      */  
  83.     private double getCpuRatioForWindows() {   
  84.         try {   
  85.             String procCmd = System.getenv("windir")   
  86.                     + "//system32//wbem//wmic.exe process get Caption,CommandLine,"  
  87.                     + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";   
  88.             // 取进程信息   
  89.             long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));   
  90.             Thread.sleep(CPUTIME);   
  91.             long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));   
  92.             if (c0 != null && c1 != null) {   
  93.                 long idletime = c1[0] - c0[0];   
  94.                 long busytime = c1[1] - c0[1];   
  95.                 return Double.valueOf(   
  96.                         PERCENT * (busytime) / (busytime + idletime))   
  97.                         .doubleValue();   
  98.             } else {   
  99.                 return 0.0;   
  100.             }   
  101.         } catch (Exception ex) {   
  102.             ex.printStackTrace();   
  103.             return 0.0;   
  104.         }   
  105.     }   
  106.   
  107.     /** *//**  
  108.      * 读取CPU信息.  
  109.      * @param proc  
  110.      * @return  
  111.      * @author amg     * Creation date: 2008-4-25 - 下午06:10:14  
  112.      */  
  113.     private long[] readCpu(final Process proc) {   
  114.         long[] retn = new long[2];   
  115.         try {   
  116.             proc.getOutputStream().close();   
  117.             InputStreamReader ir = new InputStreamReader(proc.getInputStream());   
  118.             LineNumberReader input = new LineNumberReader(ir);   
  119.             String line = input.readLine();   
  120.             if (line == null || line.length() < FAULTLENGTH) {   
  121.                 return null;   
  122.             }   
  123.             int capidx = line.indexOf("Caption");   
  124.             int cmdidx = line.indexOf("CommandLine");   
  125.             int rocidx = line.indexOf("ReadOperationCount");   
  126.             int umtidx = line.indexOf("UserModeTime");   
  127.             int kmtidx = line.indexOf("KernelModeTime");   
  128.             int wocidx = line.indexOf("WriteOperationCount");   
  129.             long idletime = 0;   
  130.             long kneltime = 0;   
  131.             long usertime = 0;   
  132.             while ((line = input.readLine()) != null) {   
  133.                 if (line.length() < wocidx) {   
  134.                     continue;   
  135.                 }   
  136.                 // 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount,   
  137.                 // ThreadCount,UserModeTime,WriteOperation   
  138.                 String caption = Bytes.substring(line, capidx, cmdidx - 1)   
  139.                         .trim();   
  140.                 String cmd = Bytes.substring(line, cmdidx, kmtidx - 1).trim();   
  141.                 if (cmd.indexOf("wmic.exe") >= 0) {   
  142.                     continue;   
  143.                 }   
  144.                 // log.info("line="+line);   
  145.                 if (caption.equals("System Idle Process")   
  146.                         || caption.equals("System")) {   
  147.                     idletime += Long.valueOf(   
  148.                             Bytes.substring(line, kmtidx, rocidx - 1).trim())   
  149.                             .longValue();   
  150.                     idletime += Long.valueOf(   
  151.                             Bytes.substring(line, umtidx, wocidx - 1).trim())   
  152.                             .longValue();   
  153.                     continue;   
  154.                 }   
  155.   
  156.                 kneltime += Long.valueOf(   
  157.                         Bytes.substring(line, kmtidx, rocidx - 1).trim())   
  158.                         .longValue();   
  159.                 usertime += Long.valueOf(   
  160.                         Bytes.substring(line, umtidx, wocidx - 1).trim())   
  161.                         .longValue();   
  162.             }   
  163.             retn[0] = idletime;   
  164.             retn[1] = kneltime + usertime;   
  165.             return retn;   
  166.         } catch (Exception ex) {   
  167.             ex.printStackTrace();   
  168.         } finally {   
  169.             try {   
  170.                 proc.getInputStream().close();   
  171.             } catch (Exception e) {   
  172.                 e.printStackTrace();   
  173.             }   
  174.         }   
  175.         return null;   
  176.     }   
  177.        
  178.     /** *//**  
  179.      * 测试方法.  
  180.      * @param args  
  181.      * @throws Exception  
  182.      * @author amg     * Creation date: 2008-4-30 - 下午04:47:29  
  183.      */  
  184.     public static void main(String[] args) throws Exception {   
  185.         IMonitorService service = new MonitorServiceImpl();   
  186.         MonitorInfoBean monitorInfo = service.getMonitorInfoBean();   
  187.         System.out.println("cpu占有率=" + monitorInfo.getCpuRatio());   
  188.            
  189.         System.out.println("可使用内存=" + monitorInfo.getTotalMemory());   
  190.         System.out.println("剩余内存=" + monitorInfo.getFreeMemory());   
  191.         System.out.println("最大可使用内存=" + monitorInfo.getMaxMemory());   
  192.            
  193.         System.out.println("操作系统=" + monitorInfo.getOsName());   
  194.         System.out.println("总的物理内存=" + monitorInfo.getTotalMemorySize() + "kb");   
  195.         System.out.println("剩余的物理内存=" + monitorInfo.getFreeMemory() + "kb");   
  196.         System.out.println("已使用的物理内存=" + monitorInfo.getUsedMemory() + "kb");   
  197.         System.out.println("线程总数=" + monitorInfo.getTotalThread() + "kb");   
  198.     }   
  199. }  

 

该实现类中需要用到一个自己编写byte的工具类,该类的代码如下所示:

Java代码 复制代码
  1. package com.amgkaka.performance;   
  2.   
  3. /** *//**  
  4.  * byte操作类.  
  5.  * @author amg * @version 1.0   
  6.  * Creation date: 2008-4-30 - 下午04:57:23  
  7.  */  
  8. public class Bytes {   
  9.     /** *//**  
  10.      * 由于String.subString对汉字处理存在问题(把一个汉字视为一个字节),因此在  
  11.      * 包含汉字的字符串时存在隐患,现调整如下:  
  12.      * @param src 要截取的字符串  
  13.      * @param start_idx 开始坐标(包括该坐标)  
  14.      * @param end_idx   截止坐标(包括该坐标)  
  15.      * @return  
  16.      */  
  17.     public static String substring(String src, int start_idx, int end_idx){   
  18.         byte[] b = src.getBytes();   
  19.         String tgt = "";   
  20.         for(int i=start_idx; i<=end_idx; i++){   
  21.             tgt +=(char)b[i];   
  22.         }   
  23.         return tgt;   
  24.     }   
  25. }  

 

运行下MonitorBeanImpl类,读者将会看到当前的内存、cpu利用率等信息

 

wmic很强大,网上有很多wmic的命令,

eg:wmic 获取物理内存
wmic memlogical get TotalPhysicalMemory

 

wmic 获取进程信息,很详细

wmic process

 

System.getProperty("os.name"));//得到操作系统名字 
System.getProperty("sun.os.patch.level");//得到操作系统版本