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