java程式碼實現檢視Tomcat記憶體使用情況

暴走的小奶牛發表於2020-10-11
  1. package com.amgkaka.performance;  
  2.   
  3. /** *//** 
  4.  * 監視資訊的JavaBean類. 
  5.  * @author  bailu
  6.  * @version 1.0  
  7.  * Creation date: 2019-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. }  

接著編寫一個獲得當前的監控資訊的介面,該類的程式碼如下所示:

  1. package com.amgkaka.performance;  
  2.   
  3. /** *//** 
  4.  * 獲取系統資訊的業務邏輯類介面. 
  5.  * @author bailu* @version 1.0  
  6.  * Creation date: 2019-3-11 - 上午10:06:06 
  7.  */  
  8. public interface IMonitorService {  
  9.     /** *//** 
  10.      * 獲得當前的監控物件. 
  11.      * @return 返回構造好的監控物件 
  12.      * @throws Exception 
  13.      * @author bailu
  14.      * Creation date: 2019-4-25 - 上午10:45:08 
  15.      */  
  16.     public MonitorInfoBean getMonitorInfoBean() throws Exception;  
  17.   

該類的實現類MonitorServiceImpl如下所示:

  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 bailu * @version 1.0 Creation date: 2019-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 bailu    * Creation date: 2019-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 bailu     * Creation date: 2019-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 bailu     * Creation date: 2019-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 bailu     * Creation date: 2019-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的工具類,該類的程式碼如下所示:

  1. package com.amgkaka.performance;  
  2.   
  3. /** *//** 
  4.  * byte操作類. 
  5.  * @author bailu * @version 1.0  
  6.  * Creation date: 2019-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. }  

相關文章