系统并未提供获取系统cpu和内存使用率的api,通过读取linux文件方式获取。
/proc/stat文件动态记录所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。所以,计算系统当前的CPU占用率的方法就是,计算在间隔较短(ms级)的时间内,cpu的各活动信息的变化量,作为当前的实时CPU占用率。
下图是执行shell命令,获取文件的内容。
user(181596)从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。;
nice(85733)从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间;
system (197165)从系统启动开始累计到当前时刻,处于核心态的运行时间;
idle (1328127)从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间;
iowait(11679)从系统启动开始累计到当前时刻,IO等待时间;
irq (5)从系统启动开始累计到当前时刻,硬中断时间;
softirq (5138)从系统启动开始累计到当前时刻,软中断时间。
这里,我们只需关心“idle”,它表示了系统的空闲时间,以及各项数值之和就是CPU的总消耗。
因此,我们以totalTime1表示第一次CPU总消耗,idelTime1表示第一次的CPU空闲时间,同理,totalTime2、IdleTime2表示第二次的相关信息,则cpu的占用率如下:
cpu总使用率 = ((totalTime2 - totalTime1)- (IdleTime2 - IdleTime1))/ (totalTime2 - totalTime1)
public static int getCpuRate() {
try {
String[] cpuInfos1 = getCpuInfo();
long startTotalCpuTimes = Long.parseLong(cpuInfos1[2])
+ Long.parseLong(cpuInfos1[3]) + Long.parseLong(cpuInfos1[4])
+ Long.parseLong(cpuInfos1[6]) + Long.parseLong(cpuInfos1[5])
+ Long.parseLong(cpuInfos1[7]) + Long.parseLong(cpuInfos1[8]);
long startIdle = Long.parseLong(cpuInfos1[5]);
Thread.sleep(200);
String[] cpuInfos2 = getCpuInfo();
long endTotalCpuTimes = Long.parseLong(cpuInfos2[2])
+ Long.parseLong(cpuInfos2[3]) + Long.parseLong(cpuInfos2[4])
+ Long.parseLong(cpuInfos2[6]) + Long.parseLong(cpuInfos2[5])
+ Long.parseLong(cpuInfos2[7]) + Long.parseLong(cpuInfos2[8]);
long endIdle = Long.parseLong(cpuInfos2[5]);
return (int) (100 * ((endTotalCpuTimes - startTotalCpuTimes) - (endIdle - startIdle)) /
(endTotalCpuTimes - startTotalCpuTimes));
} catch (Throwable e) {
CommonUtil.printThrowableMess(e);
return 0;
}
}
//读取Android系统记录cpu活动相关/proc/stat文件
private static String[] getCpuInfo() {
String[] cpuInfos = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("/proc/stat")), 1000);
String load = reader.readLine();
cpuInfos = load.split(" ");
} catch (Throwable ex) {
CommonUtil.printThrowableMess(ex);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Throwable e) {
CommonUtil.printThrowableMess(e);
}
}
}
return cpuInfos;
}
获取当前App的cpu使用率,通过读取当前应用的cpu活动记录文件/proc/pid/stat文件
如下图所示命令下查看两次当前App cpu使用情况
其中红框内的4各数字分别是:
utime 该任务在用户运行状态的时间
stime 该任务在核心运行的时间
cutime 所有已死线程在用户状态运行状态的时间
cstime 所有已死线程在核心的运行时间
所以进程的CPU使用时间processCpuTime为这个四个属性的和.
在T1时,processCpuTime1 = utime1 + stime1 + cutime1 + cstime1
在T2时,processCpuTime2 = utime2 + stime2 + cutime2 + cstime2
所以进程所占CPU的使用率算法是:
当前应用cpu使用率 = 100*(processCpuTime2-processCpuTime1) / (totalCpuTime2-totalCpuTime1)
public static long getAppCpuTime()
{ // 获取应用占用的CPU时间
String[] cpuInfos = null;
try
{
int pid = android.os.Process.myPid();
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("/proc/" + pid + "/stat")), 1000);
String load = reader.readLine();
reader.close();
cpuInfos = load.split(" ");
}
catch (IOException ex)
{
ex.printStackTrace();
}
long appCpuTime = Long.parseLong(cpuInfos[13])
+ Long.parseLong(cpuInfos[14]) + Long.parseLong(cpuInfos[15])
+ Long.parseLong(cpuInfos[16]);
return appCpuTime;
}
public static int getAppCpuRate() {
try {
String[] cpuInfos1 = getCpuInfo();
long startTotalCpuTimes = Long.parseLong(cpuInfos1[2])
+ Long.parseLong(cpuInfos1[3]) + Long.parseLong(cpuInfos1[4])
+ Long.parseLong(cpuInfos1[6]) + Long.parseLong(cpuInfos1[5])
+ Long.parseLong(cpuInfos1[7]) + Long.parseLong(cpuInfos1[8]);
long startAppCpuTimes = getAppCpuTime();
Thread.sleep(200);
String[] cpuInfos2 = getCpuInfo();
long endTotalCpuTimes = Long.parseLong(cpuInfos2[2])
+ Long.parseLong(cpuInfos2[3]) + Long.parseLong(cpuInfos2[4])
+ Long.parseLong(cpuInfos2[6]) + Long.parseLong(cpuInfos2[5])
+ Long.parseLong(cpuInfos2[7]) + Long.parseLong(cpuInfos2[8]);
long endAppCpuTimes = getAppCpuTime();
return (int) (100 * (endAppCpuTimes - startAppCpuTimes) /
(endTotalCpuTimes - startTotalCpuTimes));
} catch (Throwable e) {
CommonUtil.printThrowableMess(e);
return 0;
}
}
2.获取系统内存使用率
通过读取linux文件/proc/meminfo获取系统整体内存
private static long getTotalMemory() {
String str1 = "/proc/meminfo";
String str2;
String[] arrayOfString;
long initialMemory = 0;
FileReader localFileReader = null;
BufferedReader localBufferedReader = null;
try {
localFileReader = new FileReader(str1);
localBufferedReader = new BufferedReader(localFileReader, 8192);
str2 = localBufferedReader.readLine();
arrayOfString = str2.split("\\s+");
initialMemory = Long.parseLong(arrayOfString[1]) * 1024;
} catch (Throwable e) {
CommonUtil.printThrowableMess(e);
} finally {
if (localBufferedReader != null) {
try {
localBufferedReader.close();
} catch (Throwable e2) {
CommonUtil.printThrowableMess(e2);
}
}
if (localFileReader != null) {
try {
localFileReader.close();
} catch (Throwable e2) {
CommonUtil.printThrowableMess(e2);
}
}
}
return initialMemory;
}
通过ActivityManager获取可用内存,计算可用内存比率
public static int getAvailRamRate(Context context) {
int rate = 0;
try {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
MemoryInfo mi = new MemoryInfo();
am.getMemoryInfo(mi);
long totalMem = getTotalMemory();
long availMem = mi.availMem;
rate = (int) (availMem * 100 / totalMem);
} catch (Throwable e) {
CommonUtil.printThrowableMess(e);
}
return rate;
}