用java取得linux系統cpu、記憶體的即時資訊

來源:互聯網
上載者:User

from:http://avery-leo.javaeye.com/blog/298724

原始碼:

  1. import java.io.BufferedReader;   
  2. import java.io.File;   
  3. import java.io.FileInputStream;   
  4. import java.io.IOException;   
  5. import java.io.InputStreamReader;   
  6. import java.net.InetAddress;   
  7. import java.util.StringTokenizer;   
  8. import org.apache.log4j.Logger;   
  9. /**
  10. * 取得linux系統下的cpu、記憶體資訊
  11. * <p>
  12. * @author leo
  13. *         </p>
  14. * @date 2008
  15. */
  16. public final class LinuxSystemTool implements Runnable{   
  17. private Logger log = Logger.getLogger(LinuxSystemTool.class);   
  18. private Config config=Config.getInstance();   
  19. /**
  20.      * get memory by used info
  21.      * 
  22.      * @return int[] result
  23.      *         result.length==4;int[0]=MemTotal;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree;
  24.      * @throws IOException
  25.      * @throws InterruptedException
  26.      */
  27. public void run() {   
  28. // TODO Auto-generated method stub
  29. while (true) {   
  30.             try {   
  31.                 exec();   
  32.                 Thread.sleep(config.getThreadTime());   
  33.             } catch (Exception e) {   
  34. // TODO Auto-generated catch block
  35.                 log.error("Performance Monitoring error:"+e.getMessage());   
  36.                 e.printStackTrace();   
  37.             }   
  38.         }   
  39.     }   
  40. public void exec() throws Exception {   
  41. //      ServerStatus ss = new ServerStatus();
  42.         InetAddress inet = InetAddress.getLocalHost();   
  43.         System.out.println("Performance Monitoring ip:"+inet.toString());   
  44.         String ip=inet.toString().substring(inet.toString().indexOf("/")+1);   
  45.         log.info("Performance Monitoring ip:"+ip);   
  46.         int[] memInfo = LinuxSystemTool.getMemInfo();   
  47.         System.out.println("MemTotal:" + memInfo[0]);   
  48.         System.out.println("MemFree:" + memInfo[1]);   
  49.         SnmpUtil util=new SnmpUtil();   
  50.         util.setCPU(getCpuInfo());   
  51. //      util.setDISK(1);
  52.         util.setMEM(memInfo[0]/memInfo[1]);   
  53.         util.setIP(ip);   
  54. }   
  55. public static int[] getMemInfo() throws IOException, InterruptedException {   
  56.         File file = new File("/proc/meminfo");   
  57.         BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));   
  58.         int[] result = new int[4];   
  59.         String str = null;   
  60.         StringTokenizer token = null;   
  61.         while ((str = br.readLine()) != null) {   
  62.             token = new StringTokenizer(str);   
  63.             if (!token.hasMoreTokens())   
  64.                continue;   
  65.             str = token.nextToken();   
  66.             if (!token.hasMoreTokens())   
  67.                continue;   
  68.             if (str.equalsIgnoreCase("MemTotal:"))   
  69.                 result[0] = Integer.parseInt(token.nextToken());   
  70.             else if (str.equalsIgnoreCase("MemFree:"))   
  71.                 result[1] = Integer.parseInt(token.nextToken());   
  72.             else if (str.equalsIgnoreCase("SwapTotal:"))   
  73.                 result[2] = Integer.parseInt(token.nextToken());   
  74.             else if (str.equalsIgnoreCase("SwapFree:"))   
  75.                 result[3] = Integer.parseInt(token.nextToken());   
  76.          }   
  77.          return result;   
  78.     }   
  79. /**
  80.      * get memory by used info
  81.      * 
  82.      * @return float efficiency
  83.      * @throws IOException
  84.      * @throws InterruptedException
  85.      */
  86. public static float getCpuInfo() throws IOException, InterruptedException {   
  87.         File file = new File("/proc/stat");   
  88.         BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(file)));   
  89.         StringTokenizer token = new StringTokenizer(br.readLine());   
  90.         token.nextToken();   
  91.         long user1 = Long.parseLong(token.nextToken());   
  92.         long nice1 = Long.parseLong(token.nextToken());   
  93.         long sys1 = Long.parseLong(token.nextToken());   
  94.         long idle1 = Long.parseLong(token.nextToken());   
  95.         Thread.sleep(1000);   
  96.         br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));   
  97.         token = new StringTokenizer(br.readLine());   
  98.         token.nextToken();   
  99.         long user2 = Long.parseLong(token.nextToken());   
  100.         long nice2 = Long.parseLong(token.nextToken());   
  101.         long sys2 = Long.parseLong(token.nextToken());   
  102.         long idle2 =Long.parseLong(token.nextToken());
  103.         return (float) ((user2 + sys2 + nice2) - (user1 + sys1 + nice1))   
  104.                 / (float) ((user2 + nice2 + sys2 + idle2) - (user1 + nice1+ sys1 + idle1));   
  105.     }   
  106. /**
  107.      * 測試類別
  108.      * 
  109.      * <p>
  110.      * 
  111.      * @author
  112.      * </p>
  113.      * @date
  114.      */
  115. public static void main(String[] args) throws Exception {   
  116.         int[] memInfo = LinuxSystemTool.getMemInfo();   
  117.         System.out.println("MemTotal:" + memInfo[0]);   
  118.         System.out.println("MemFree:" + memInfo[1]);   
  119.         System.out.println("SwapTotal:" + memInfo[2]);   
  120.         System.out.println("SwapFree:" + memInfo[3]);   
  121.         System.out.println("CPU利用率:" + LinuxSystemTool.getCpuInfo());   
  122.     }   

註:原文使用int儲存cpu計數值,欠妥。在長期啟動並執行伺服器上可能導致轉化值溢出。

1.CPU

在檔案"/proc/stat"裡面就包含了CPU的資訊。每一個CPU的每一tick用在什麼地方都在這個檔案裡面記著。後面的數字含義分別是: user、nice、sys、idle、iowait。有些版本的kernel沒有iowait這一項。這些數值表示從開機到現在,CPU的每tick用在了哪裡。例如:

cpu0 256279030 0 11832528 1637168262

就是cpu0從開機到現在有 256279030 tick用在了user消耗,11832528用在了sys消耗。所以如果想計算單位時間(例如1s)裡面CPU的負載,那隻需要計算1秒前後數值的差除以每一秒的tick數量就可以了。gkrellm就是這樣實現的:((200 * (v2 - v1) / CPU_TICKS_PER_SECOND) + 1) /2

例如,第一次讀取/proc/stat,user的值是256279030;一秒以後再讀一次,值是256289030,那麼CPU在這一秒的user消耗就是:((200 * (256289030 - 256279030) / CPU_TICKS_PER_SECOND) + 1) /2 = ((10000 * 200 / 1000000) + 1) / 2 = 1%了。

2、記憶體消耗

檔案"/proc/meminfo"裡麵包含的就是記憶體的資訊,還包括了swap的資訊。例如:

$ cat /proc/meminfo

total:    used:    free: shared: buffers: cached:
Mem: 1057009664 851668992 205340672        0 67616768 367820800
Swap: 2146787328 164429824 1982357504
MemTotal:      1032236 kB
MemFree:        200528 kB
MemShared:           0 kB
……

不過從gkrellm的原始碼看,有些版本沒有前面那兩行統計的資訊,只能夠根據下面的Key: Value這種各式的資料收集。

3、磁碟空間

從gkrellm的原始碼看,這個是一個很複雜的資料。磁碟分割的資料有可能分布在:/proc/mounts、/proc/diskstats、 /proc/partitions等等。而且如果想要檢查某幾個特定的路徑,還需要通過mount、df等命令的協助。為了減少麻煩,這個資料我就直接用 statfs函數直接獲得了。

int statfs(const char *path, struct statfs *buf);

這個函數只需要輸入需要檢查的路徑名稱,就可以返回這個路徑所在的分區的空間使用方式:

總空間:buf.f_bsize * buf.f_blocks

空餘空間:buf.f_bsize * buf.f_bavail

4、磁碟I/O

磁碟I/O的資料也同樣比較複雜,有些版本看/proc/diskstats,有些版本看/proc/partitions,還有些版本至今我也不知道在那裡看……不過可以看到資料的版本也像CPU那樣,需要隔一段時間取值,兩次取值的差就是流量。

5、網路流量

網路流量也是五花八門,不過基本上都可以在/proc/net/dev裡面獲得。同樣也是需要兩次取值取其差作為流量值。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.