Linux 下CPU、內存利用率--計算(二)

  
Linux CPU、內存利用率--計算(二)
當需要頻繁地獲取,可以選擇這種方法。
1、原理
(1)   CPU利用率
Linux下,CPU利用率分爲用戶態,系統態和空閒態,分別表示CPU處於用戶態執行的時間,系統內核執行的時間,和空閒系統進程執行的時間,三者之和就是CPU的總時間,當沒有用戶進程、系統進程等需要執行的時候,CPU就執行系統缺省的空閒進程。從平常的思維方式理解的話,CPU的利用率就是非空閒進程佔用時間的比例,即CPU執行非空閒進程的時間 / CPU總的執行時間。
Linux系統中,CPU時間的分配信息保存在/proc/stat文件中,利用率的計算應該從這個文件中獲取數據。文件的頭幾行記錄了每個CPU的用戶態,系統態,空閒態等狀態下分配的時間片(單位是Jiffies),這些數據是從CPU加電到當前的累計值。常用的監控軟件就是利用/proc/stat裏面的這些數據來計算CPU的利用率的。
不同版本的linux /proc/stat文件內容不一樣,以Linux 2.6來說,/proc/stat文件的內容如下:
 
cpu 2032004 102648 238344 167130733 758440 15159 17878 0
cpu0 1022597 63462 141826 83528451 366530 9362 15386 0
cpu1 1009407 39185 96518 83602282 391909 5796 2492 0
intr 303194010 212852371 3 0 0 11 0 0 2 1 1 0 0 3 0 11097365 0 72615114 6628960 0 179 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 236095529
btime 1195210746
processes 401389
procs_running 1
procs_blocked 0
 
第一行的數值表示的是CPU總的使用情況,所以我們只要用第一行的數字計算就可以了。下表解析第一行各數值的含義:
參數
解析(單位:jiffies
user (2032004)
從系統啓動開始累計到當前時刻,用戶態的CPU時間,不包含 nice值爲負進程。
nice (102648)
從系統啓動開始累計到當前時刻,nice值爲負的進程所佔用的CPU時間
system (238344)
從系統啓動開始累計到當前時刻,核心時間
idle (167130733)
從系統啓動開始累計到當前時刻,除硬盤IO等待時間以外其它等待時間
iowait (758440)
從系統啓動開始累計到當前時刻,硬盤IO等待時間
irq (15159)
從系統啓動開始累計到當前時刻,硬中斷時間
softirq (17878)
從系統啓動開始累計到當前時刻,軟中斷時間
 
 
因爲/proc/stat中的數值都是從系統啓動開始累計到當前時刻的積累值,所以需要在不同時間點t1t2取值進行比較運算,當兩個時間點的間隔較短時,就可以把這個計算結果看作是CPU的即時利用率。
 
CPU的即時利用率的計算公式:
CPUt1t2時間段總的使用時間 = ( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1)
CPUt1t2時間段空閒使用時間 = (idle2 - idle1)
CPUt1t2時間段即時利用率 =  1 - CPU空閒使用時間 / CPU總的使用時間
 
 
2)內存利用率
計算內存利用率需要從/proc/meminfo文件中取相應數據,文件內容如下:
MemTotal:      1024008 kB
MemFree:         18448 kB
Buffers:         12664 kB
Cached:         282500 kB
SwapCached:        716 kB
Active:         816124 kB
Inactive:        52516 kB
HighTotal:      122500 kB
HighFree:          304 kB
 
… …
 
MemTotal數值表示內存總量,MemFree數值表示空餘數量。
所以內存的即時利用率計算公式
(MemTotal - MemFree)/ MemTotal
 
 
2、實現
 這個例子適合於linux內核是2.6版本。Linux的版本問題請參照Linux 下CPU、內存利用率--獲取(一)
 

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


public class MonitorUsageThread extends Thread{
    
    
private final int frequency;//MS
    private static final File memFile = new File("/proc/meminfo");
    
private static final File statFile = new File("/proc/stat");
    
private static BufferedReader brMem ;
    
private static BufferedReader brStat ;
    
private static InputStreamReader isr = null;
    
    
private static float cpuUsage;
    
private static float memUsage;
    
    
private static boolean on = true;
    
public MonitorUsageThread(int frequency){
        
this.frequency = frequency;
    }

    
    
    
public void run(){
        System.out.println(
"MonitorUsageThread start run ..................... on: "+on);
        String str 
= null;
        StringTokenizer tokenMem 
= null;
        
int memTotal = 0;
        
int memFree = 0;
        
int userStart,niceStart,sysStart,idleStart,iowaitStart,hardirpStart,softirpStart,userEnd,niceEnd,sysEnd,idleEnd,iowaitEnd,hardirpEnd,softirpEnd;
        
try {
            isr 
= new InputStreamReader(new FileInputStream(statFile));
            brStat 
= new BufferedReader(isr);
            StringTokenizer tokenStat 
= new StringTokenizer(brStat.readLine());
            tokenStat.nextToken();
            userStart 
= Integer.parseInt(tokenStat.nextToken());
            niceStart 
= Integer.parseInt(tokenStat.nextToken());
            sysStart 
= Integer.parseInt(tokenStat.nextToken());
            idleStart 
= Integer.parseInt(tokenStat.nextToken());
            iowaitStart 
= Integer.parseInt(tokenStat.nextToken());
            hardirpStart 
= Integer.parseInt(tokenStat.nextToken());
            softirpStart 
= Integer.parseInt(tokenStat.nextToken());
            Thread.sleep(frequency);
            
while(on){
                isr 
= new InputStreamReader(new FileInputStream(statFile));
                brStat 
= new BufferedReader(isr);
                tokenStat 
= new StringTokenizer(brStat.readLine());
                tokenStat.nextToken();
                userEnd 
= Integer.parseInt(tokenStat.nextToken());
                niceEnd 
= Integer.parseInt(tokenStat.nextToken());
                sysEnd 
= Integer.parseInt(tokenStat.nextToken());
                idleEnd 
= Integer.parseInt(tokenStat.nextToken());
                iowaitEnd 
= Integer.parseInt(tokenStat.nextToken());
                hardirpEnd 
= Integer.parseInt(tokenStat.nextToken());
                softirpEnd 
= Integer.parseInt(tokenStat.nextToken());
                

                
int CPUEnd = userEnd+niceEnd+sysEnd+idleEnd+iowaitEnd+hardirpEnd+softirpEnd;
                
int CPUStart = userStart+niceStart+sysStart+idleStart+iowaitStart+hardirpStart+softirpStart;
                System.out.println(
"idleEnd:"+idleEnd+" , idleStart:"+idleStart+"   ,CPUEnd:"+CPUEnd+" , CPUStart:"+CPUStart);
                
                cpuUsage 
= 1- (float)(idleEnd - idleStart) / (float)(CPUEnd - CPUStart);// cpu usage

                
//Gets memory information
                isr = new InputStreamReader(new FileInputStream(memFile));
                brMem 
= new BufferedReader(isr);
                
                str 
= brMem.readLine();
                tokenMem 
= new StringTokenizer(str);
                tokenMem.nextToken();
                memTotal 
= Integer.parseInt(tokenMem.nextToken());
                
                str 
= brMem.readLine();
                tokenMem 
= new StringTokenizer(str);
                tokenMem.nextToken();
                memFree 
= Integer.parseInt(tokenMem.nextToken());
                        
                System.out.println(
"MemTotal:"+memTotal+" , MemFree:"+memFree);
                memUsage 
= (float)(memTotal-memFree) / (float)memTotal;// memory usage 
                
                userStart 
= userEnd;
                niceStart 
= niceEnd;
                sysStart 
= sysEnd;
                idleStart 
= idleEnd;
                iowaitStart 
= iowaitEnd;
                hardirpStart 
= hardirpEnd;
                softirpStart 
= softirpEnd;

                System.out.println(
"Rate of CPU usage is "+cpuUsage+" , and the memory's is "+memUsage+"  ");
                Thread.sleep(frequency);
//
            }

                
                
        }
 catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }
 catch (InterruptedException ie) {
            System.out.println(ie.getMessage());
        }
 finally{
            freeResource();
        }


    }

              
    
    
private static void freeResource(){
        
try{
            
if(isr!=null)
                isr.close();
            
if(brMem!=null)
                brMem.close();
            
if(brStat!=null)
                brStat.close();
        }
catch(IOException ioe){
            System.out.println(ioe.getMessage());
        }

    }

    
    
public static float getCPUUsage(){
        
return cpuUsage;
    }

    
    
    
public static float getMemoryUsage(){
        
return memUsage;
    }

    
    
public static void stopMonitor(){
        on 
= false;
        freeResource();
    }

    
    
    
    
public static void main(String[] args){
        MonitorUsageThread thread 
= new MonitorUsageThread(2000);
        thread.start();
        
try{
            Thread.sleep(
10000);//MS
        }
catch(InterruptedException ie){
            ie.printStackTrace();
        }

        System.out.println();
        System.out.println(
"-------------CPU usage: "+getCPUUsage());
        System.out.println(
"-------------Memory usage: "+getMemoryUsage());
        
        
try{
            Thread.sleep(
5000);//MS
        }
catch(InterruptedException ie){
            ie.printStackTrace();
        }

        System.out.println();
        System.out.println(
"-------------CPU usage: "+getCPUUsage());
        System.out.println(
"-------------Memory usage: "+getMemoryUsage());
        
        
        thread.stopMonitor();
        System.exit(
0);
    }

    
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章