实时统计Android应用的CPU和内存占用

一、应用CPU实时统计

1.1CPU总使用情况

在proc/stat下有当前设备详细的CPU使用情况.详细格式如下:

CPU 152342 1421 28562 1600830 12389 553 273 0 0

CPU后面的几位数字的含义分别是

user 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。 
nice 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间 
system 从系统启动开始累计到当前时刻,处于核心态的运行时间 
idle 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间 
iowait 从系统启动开始累计到当前时刻,IO等待时间 
irq 从系统启动开始累计到当前时刻,硬中断时间 
softirq 从系统启动开始累计到当前时刻,软中断时间

所以totalCpuTime这个7个属性的和.

1.2当前应用的CPU使用情况

/proc/pid/stat下则是该pid的CPU使用情况.详细格式如下:

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 该任务在用户运行状态的时间 
612:stime 该任务在核心运行的时间

所以processCpuTime为这个两个个属性的和.

1.3应用的CPU占用

当前应用所占CPU的算法是:

扫描二维码关注公众号,回复: 3201438 查看本文章
100*(processCpuTimeNow - processCpuTimeLast)/(totalCpuTimeNow - totalCpuTimeLast)
  • 1
  • 2

二、应用内存占用统计

统计当前应用的内存占用的方式: 
(1)从ActivityManager获得MemoryInfo 
(2)从MemoryInfo里获得TotalPss:memInfo[0].getTotalPss(),其中TotalPss = dalvikPss + nativePss + otherPss

三、DEMO

开启一个周期性的任务打印实时CPU和内存占用 

import android.app.ActivityManager;
import android.content.Context;
import android.os.Debug;
import android.os.Process;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 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 final String relativeSavePath = "sourceSummary.txt";
    private String savePath;
    private StringBuilder surveyBuffer;
    private long count;

    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, String savePath) {
        activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        this.freq = freq;
        this.savePath = savePath + relativeSavePath;
        surveyBuffer = new StringBuilder();
        count = 1;
    }

    public void start() {
        scheduler.scheduleWithFixedDelay(this, 0L, freq, TimeUnit.MILLISECONDS);
    }

    public void writeDown() {
        try{
            File saveFile = new File(savePath);
            saveFile.createNewFile();
            BufferedWriter writer = new BufferedWriter(new FileWriter(saveFile));
            writer.write(surveyBuffer.toString());
            writer.flush();
            writer.close();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        double cpu = sampleCPU();
        double mem = sampleMemory();
        surveyBuffer.append(count++ + ": CPU: " + cpu + "%" + ", Memory: " + mem + "MB\r\n");
    }

    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 {
            // 统计进程的内存信息 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;
    }
}

转载自:https://blog.csdn.net/hello2mao/article/details/68503780

猜你喜欢

转载自blog.csdn.net/a40850273/article/details/81511999