一善延、應(yīng)用CPU實(shí)時(shí)統(tǒng)計(jì)
1.1CPU總使用情況
在proc/stat下有當(dāng)前設(shè)備詳細(xì)的CPU使用情況.詳細(xì)格式如下:
CPU 152342 1421 28562 1600830 12389 553 273 0 0
CPU后面的幾位數(shù)字的含義分別是
user 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻,處于用戶態(tài)的運(yùn)行時(shí)間庶柿,不包含 nice值為負(fù)進(jìn)程。
nice 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻褥伴,nice值為負(fù)的進(jìn)程所占用的CPU時(shí)間
system 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻返吻,處于核心態(tài)的運(yùn)行時(shí)間
idle 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻萧恕,除IO等待時(shí)間以外的其它等待時(shí)間
iowait 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻刚梭,IO等待時(shí)間
irq 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻肠阱,硬中斷時(shí)間
softirq 從系統(tǒng)啟動(dòng)開始累計(jì)到當(dāng)前時(shí)刻票唆,軟中斷時(shí)間
所以totalCpuTime這個(gè)7個(gè)屬性的和.
1.2當(dāng)前應(yīng)用的CPU使用情況
/proc/pid/stat下則是該pid的CPU使用情況.詳細(xì)格式如下:
2341 (com.xxxx.xxxx) S 1131 1131 0 0 -1 3912246 12450 0 2 0 3321 612 0 0 20 0
其中3321 612的含義分別是:
3321:utime 該任務(wù)在用戶運(yùn)行狀態(tài)的時(shí)間
612:stime 該任務(wù)在核心運(yùn)行的時(shí)間
所以processCpuTime為這個(gè)兩個(gè)個(gè)屬性的和.
1.3應(yīng)用的CPU占用
當(dāng)前應(yīng)用所占CPU的算法是:
100*(processCpuTimeNow - processCpuTimeLast)/(totalCpuTimeNow - totalCpuTimeLast)
二、應(yīng)用內(nèi)存占用統(tǒng)計(jì)
統(tǒng)計(jì)當(dāng)前應(yīng)用的內(nèi)存占用的方式:
(1)從ActivityManager獲得MemoryInfo
(2)從MemoryInfo里獲得TotalPss:memInfo[0].getTotalPss()屹徘,其中TotalPss = dalvikPss + nativePss + otherPss
三走趋、DEMO
開啟一個(gè)周期性的任務(wù)打印實(shí)時(shí)CPU和內(nèi)存占用
源碼地址:https://github.com/hello2mao/CPUMemDemo
/**
* Usage:
* Sampler.getInstance().init(getApplicationContext(), 100L);
* Sampler.getInstance().start();
*/
public class Sampler implements Runnable {
private volatile static Sampler instance = null;
private ScheduledExecutorService scheduler;
private ActivityManager activityManager;
private long freq;
private Long lastCpuTime;
private Long lastAppCpuTime;
private RandomAccessFile procStatFile;
private RandomAccessFile appStatFile;
private Sampler() {
scheduler = Executors.newSingleThreadScheduledExecutor();
}
public static Sampler getInstance() {
if (instance == null) {
synchronized (Sampler.class) {
if (instance == null) {
instance = new Sampler();
}
}
}
return instance;
}
// freq為采樣周期
public void init(Context context, long freq) {
activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
this.freq = freq;
}
public void start() {
scheduler.scheduleWithFixedDelay(this, 0L, freq, TimeUnit.MILLISECONDS);
}
@Override
public void run() {
double cpu = sampleCPU();
double mem = sampleMemory();
Log.d("Sampler", "CPU: " + cpu + "%" + " Memory: " + mem + "MB");
}
private double sampleCPU() {
long cpuTime;
long appTime;
double sampleValue = 0.0D;
try {
if (procStatFile == null || appStatFile == null) {
procStatFile = new RandomAccessFile("/proc/stat", "r");
appStatFile = new RandomAccessFile("/proc/" + Process.myPid() + "/stat", "r");
} else {
procStatFile.seek(0L);
appStatFile.seek(0L);
}
String procStatString = procStatFile.readLine();
String appStatString = appStatFile.readLine();
String procStats[] = procStatString.split(" ");
String appStats[] = appStatString.split(" ");
cpuTime = Long.parseLong(procStats[2]) + Long.parseLong(procStats[3])
+ Long.parseLong(procStats[4]) + Long.parseLong(procStats[5])
+ Long.parseLong(procStats[6]) + Long.parseLong(procStats[7])
+ Long.parseLong(procStats[8]);
appTime = Long.parseLong(appStats[13]) + Long.parseLong(appStats[14]);
if (lastCpuTime == null && lastAppCpuTime == null) {
lastCpuTime = cpuTime;
lastAppCpuTime = appTime;
return sampleValue;
}
sampleValue = ((double) (appTime - lastAppCpuTime) / (double) (cpuTime - lastCpuTime)) * 100D;
lastCpuTime = cpuTime;
lastAppCpuTime = appTime;
} catch (Exception e) {
e.printStackTrace();
}
return sampleValue;
}
private double sampleMemory() {
double mem = 0.0D;
try {
// 統(tǒng)計(jì)進(jìn)程的內(nèi)存信息 totalPss
final Debug.MemoryInfo[] memInfo = activityManager.getProcessMemoryInfo(new int[]{Process.myPid()});
if (memInfo.length > 0) {
// TotalPss = dalvikPss + nativePss + otherPss, in KB
final int totalPss = memInfo[0].getTotalPss();
if (totalPss >= 0) {
// Mem in MB
mem = totalPss / 1024.0D;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return mem;
}
}