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