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 中的数值都是从系统启动开始累计到当前时刻的积累值,所以需要在不同时间点 t1 t2 取值进行比较运算,当两个时间点的间隔较短时,就可以把这个计算结果看作是 CPU 的即时利用率。
 
CPU 的即时利用率的计算公式:
CPU t1 t2 时间段总的使用时间 = ( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1)
CPU t1 t2 时间段空闲使用时间 = (idle2 - idle1)
CPU t1 t2 时间段即时利用率 =  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);
    }

    
}




你可能感兴趣的:(Linux/Unix)