美文网首页
Android 获取APP自身的CPU使用率

Android 获取APP自身的CPU使用率

作者: 小强开学前 | 来源:发表于2022-09-11 23:47 被阅读0次

    目前 top,dumpsys cpuinfo,/proc/stat这些都被谷歌以安全为由禁止访问了
    但是性能监控(APM)的需求还是有的,这里也只是分享如何获取自身进程的CPU使用率

    public class APM{
    
        // Linux 默认时钟频率为 100 HZ
        private int CLK_TCK = 100;
        // 上次的CPU使用时间
        private long lastUsedCPUTime = 0L;
        // 上次的CPU记录时间
        private long lastRecordCPUTime = SystemClock.uptimeMillis();
        // 存储 CPU 使用信息的文件
        private final File pidStatFile = new File("/proc/" + Process.myPid() + "/stat");
        // 获取 时钟频率 的命令
        private final String[] cmd = {"sh", "-c", "getconf CLK_TCK"};
    
       /**
         * 计算方法 ∆(uTime + sTime) / ∆upTimeMillis / 1000 * CLK_TCK / CORE_COUNT
         * 计算方法 进程运行时间片数 / (已过去时间 * 时钟频率 * 可用核心数)
         *
         * @return 当前CPU使用率%(from 0 to 100)
         */
        private float getCpuUsage() {
            try (FileInputStream inputStream = new FileInputStream(pidStatFile);
                 InputStreamReader reader = new InputStreamReader(inputStream);
                 BufferedReader bufferedReader = new BufferedReader(reader)
            ) {
                String line = bufferedReader.readLine();
                String[] res = line.split(" ");
                // 进程在用户态运行的时间
                long uTime = Long.parseLong(res[13]);
                // 进程在内核态运行的时间
                long sTime = Long.parseLong(res[14]);
                // 本次运行总时间
                long usedTime = (uTime + sTime) - lastUsedCPUTime;
    
                long currentTime = SystemClock.uptimeMillis();
                // 获得已过去时间 ms ==> s ==> Clock Tick
                float elapsedTime = (currentTime - lastRecordCPUTime) / 1000f * CLK_TCK;
    
                lastUsedCPUTime = uTime + sTime;
                lastRecordCPUTime = currentTime;
    
                float usage = usedTime / elapsedTime * 100;
                return usage / Runtime.getRuntime().availableProcessors();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0f;
        }
    
        /**
         * 确保时钟频率正确,以防厂商定制
         * 测试 坚果1 Android5.1 获取参数失败,但默认也是 100
         */
        private void configClkTck() {
            try {
                java.lang.Process process = Runtime.getRuntime().exec(cmd);
                try (InputStream inputStream= process.getInputStream();
                     InputStreamReader reader = new InputStreamReader(inputStream);
                     BufferedReader bufferedReader = new BufferedReader(reader)){
                    CLK_TCK = Integer.parseInt(bufferedReader.readLine());
                }
                process.destroy();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    大致思路就是T1时间 uTime + sTime 与 T2时间 uTime + sTime 差值,除以总时间片数,当然还要考虑多核的情况。

    • uTime + sTime 可以获得此进程到现在为止已经使用的CPU时间片数

    • 另外还有两个参数可以获得此进程的子进程的 uTime + sTime, 叫做 cutime 和 cstime

    • CPU每有固定换片次数,这与CPU频率有关,Linux 一般固定为100,可以通过getconf CLK_TCK查询。

    大概就是:

    ∆appCPUUsage / (∆time * CLK_TCK * coreCount)

    自测与Debug环境下的TOP命令查看的结果相差不到1%。

    相关文章

      网友评论

          本文标题:Android 获取APP自身的CPU使用率

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