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);
}
}



