美文网首页Android葵花宝典
Android性能监控之参数读取方式

Android性能监控之参数读取方式

作者: 小红军storm | 来源:发表于2018-02-02 19:18 被阅读43次

    1、Android性能参数的获取方式包括以下三种来源:
    1.1、是Android从linux继承来的特性,与进程相关的信息会保存在文件/proc中,监控工具做的事情就是去读取解析文件;
    1.2、是Android系统提供的API,监控工具直接调API再进行相应的处理既可;
    1.3、是从Android命令中获取需要的数据,监控工具先采用Runtime调用命令获取命令返回值进而解析处理得到需要的数据。
    下文分别针对常见的几种数据获取原理进行介绍。

    2、PID/UID概念及获取

    上面提到的三种方法,前两个都需要有一个参数,有了这个参数,才能把数据文件和应用对应起来,这个参数通常是PID或者UID。

    说到PID,UID,这里简单介绍一下,与linux、windows一样,Android中PID标识的也是进程号,其实一个Android应用可以是单进程,也可以是多个进程,多进程时一个App则对应多个PID,且App退出(进程销毁)再打开后进程号通常会被系统重新分配。UID与PID不同,UID与Android应用是一一对应的,是应用的身份标识,UID是App安装后固定不变的。

    PID的获取其实并没有非常直接的API(比如根据App包名查询到),通常是采用曲线的方式,Android中可以获取所有当前运行的App应用进程,通过遍历查询这些进程的包名信息是否与被监控的App包名信息一致,来得到App的当前运行进程。

    获取进程后即可通过查询该进程信息的属性得到PID,UID也可以通过相同方法获得。当然如果这个App当前并没有在运行,那么PID则获取不到。但是当App不在运行的时候,UID的获取可以直接使用API获取得到。

    有了PID和UID,可以开始讨论其他数据的获取原理了。

    3、/proc文件
    /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。
    由于系统的信息,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。 从proc文件中我们可以获取cup、内存等实时信息。

    4、cpu信息获取
    4.1、进程cpu数据
    进程CPU数据是根据PID通过读取系统文件(/proc/PID/stat)得到。读取文件后,根据该文件参数定义挑选出该进程使用的CPU时间,以百度外卖app为例,如下图。重点关注每行中的第14~17个数据,这四个值分别是utime,stime,cutime,cstime。其含义为:
    utime,进程在用户代码执行的累积时间,单位为jiffies
    stime, 进程在内核代码执行的累积时间,单位为jiffies
    cutime,进程在用户代码等待线程执行的累积时间,单位为jiffies
    cstime,进程在内核代码等待线程执行的累积时间,单位为jiffies
    进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime

    百度外卖app主进程cpu使用详情.png

    4.2、进程cpu占用率
    注意,上面说到四个值都是累积值,既然是累积值,如果想得到CPU的瞬时值,则需要取到A时刻和B时刻的CPUTime值,相减即得到A时刻到B时刻该进程增加的CPUTime,最后只要除以A时刻到B时刻整体cpu增加的CPUTime即得到该进程的CPU占用率 了。
    CPU占用率 = (进程CPUTime2-进程CPUTime1)/(系统CPUTime2-系统CPUTime1) 。

    4.3、整体cpu占用率
    整体cpu占用数据可以通过读取系统文件/proc/stat得到,如下图。看第一行到第五行,cpu代表整体的cpu数据,cpu0-cpu3代表手机每个cpu的数据,从图中可以看出,我们使用的测试手机是四核。以第一行数据为例,cpu后面各个数值的含义如下
    user 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。
    nice 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
    system 从系统启动开始累计到当前时刻,处于核心态的运行时间
    idle 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间
    iowait 从系统启动开始累计到当前时刻,IO等待时间
    irq 从系统启动开始累计到当前时刻,硬中断时间
    softirq 从系统启动开始累计到当前时刻,软中断时间
    总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq

    其中,第4个数值代表系统开机后累积的空闲值,A时刻到B时刻消耗的cpu时间则可以通过B时刻的开机累积时间减去A时刻的开机累积时间得到。利用空闲值则可以得到从A时刻到B时刻的整体CPU占用率。

    故整体cpu的占用率 = (整体CPUTime2- idle2)-(整体CPUTime1- idle1)/(整体CPUTime2-整体CPUTime1) 整体cpu使用详情.png

    5、内存
    5.1、进程内存
    安卓内存占用可用以下四个概念作为衡量
    VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
    RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
    PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
    USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
    一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

    对于进程内存的获取不需要读取/proc文件,也没有像CPUTime存在累积的概念,安卓系统给我们提供了获取进程占用内存的API。只需要将进程的PID作为参数传递给相应API即可获取到,代码如下,通常我们采用USS做为衡量标准。

    public int getPidMemorySize(int pid, Context context) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            int[] myMempid = new int[] { pid };
            Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(myMempid);
            memoryInfo[0].getTotalSharedDirty();
    //      int memSize = memoryInfo[0].getTotalPss();
            int memSize = memoryInfo[0].getTotalPrivateDirty();
            return memSize;
        }
    

    5.2、系统总内存/剩余内存

    系统总内存、剩余内存均可以通过读取/proc/meminfo文件来获取。如下图所示,直接读取值即可。 系统内存.png

    6 、流量数据
    流量数据的获取是通过UID。有两种获取方式:1、安卓系统提供的API;2、读取"/proc/uid_stat/" + uid + "/tcp_rcv"和/proc/uid_stat/" + uid + "/tcp_snd"文件。其中API获取方式如下图:

    rcvTraffic = TrafficStats.getUidRxBytes(Integer.parseInt(uid));
    sndTraffic = TrafficStats.getUidTxBytes(Integer.parseInt(uid));
    

    相关文章

      网友评论

        本文标题:Android性能监控之参数读取方式

        本文链接:https://www.haomeiwen.com/subject/jlcjzxtx.html