Android 耗时分析(adb shell/Studio CPU Profiler/插桩Trace API)

1.adb logcat 查看冷启动时间和Activity显示时间:

过滤Displayed关键字,可看到Activity的显示时间
在这里插入图片描述
那上面display后面的是时间是指包含哪些过程的时间呢?

模拟在Application中沉睡1秒操作,冷启动情况下:
在这里插入图片描述
从上可知:在冷启动情况下,第一个activity的display是冷启动的总时间=application+Activity的时间。

接着,界面上点击按钮,随意启动一个Activity:
在这里插入图片描述
从上可知:app进程在线情况下,启动activity的display 时间才是activity的显示时间(onCreate()->onStart()->onResume())

2.adb shell 启动activity的时间

格式:

adb shell am start -W package名/包名路径的activity

例如,执行打开指定的mainActivity,如下图所示:
在这里插入图片描述
解读以上数据

  • TotalTime: 是Activity的启动时间 ,与adb logcat 中Display 时间规则一致(通常以这个时间为准)
  • WaitTime: 是AMS启动Activity的总耗时(它会TotalTime更大,存在跨进程通讯回执时间)

通过adb shell 启动的activity 必须具备以下条件之一:

设置程序的主入口:
在这里插入图片描述
或者设置exported为true
在这里插入图片描述

3.AndroidStudio的cpu Profile:

3.1适用于app冷启动时的trace捕捉

创建一个新的运行configurations, 在profiling中配置:
在这里插入图片描述
一般是选择 java method sample,即Profiler的sample 模式,对性能影响小。系统会间隔us周期性记录java方法的调用栈,记录较为耗时,耗时较少不会显示在trace中。

  • Java method trace: 适用于精确记录方法执行时间,即profiler的instrument模式,因一直记录方法的调用栈和cpu 使用情况,对性能影响很大,可能会造成黑屏,卡顿等情况。
  • CallStack sample 适用于记录natvie+java的方法分析,Profiler的sample 模式。
  • System trace: 记录同一个过程中系统各个进程的trace,适合更复杂的分析耗时。

使用方式: 先使用java method sample 记录,找出耗时的所在;接着,再用 java method trace 精确分析真正的耗时时间。

点击profiler 按钮后,等待安装后,启动后,会自动开始捕捉,等执行完需要观察的流程后,点击stop 。

在这里插入图片描述
打开录制的trace文件,选择main 主线程,打开如下所示:

在这里插入图片描述
从上面,可以清楚看到app 主线程中每个环节的方法调用栈和耗时时间等。 带颜色的方块越长,耗时越多,绿色一般是app中的代码。

选择Application的onCreate()查看,双击该方法,出现如下所示:

在这里插入图片描述
通过上图,可知左边菜单可知该方法耗时1s ,右边菜单top down 可知该方法的调用栈,真正耗时所在,沉睡一秒导致。

3.2 app 运行时,记录trace

有些界面是在app 特殊情况下触发,捕获该流程的trace 。可通过usb 连接手机,其次,在profiler 界面中选择可debug的进程,如下图所示:
在这里插入图片描述
选择cpu ,双击,如下所示:
在这里插入图片描述
在这里插入图片描述
也可以自由配置记录条件,选择不同缓存大小和周期时间us。

选择需要记录的trace类型,然后在app中使用流程,点击stop 。比如,打开一个视频页面,想了解其播放过程的耗时,如下所示:

在这里插入图片描述
从top down 中可清楚看到,视频页面中播放视频testPlay()的调用时间。

4.插桩使用Debug#trace api 精准记录方法执行时间

插桩方式,在release和debug 包下都可以使用,比较灵活方便。

由于存在 8MB 的缓冲区空间限制,因此 Debug API 中的 startMethodTracing(String tracePath) 方法专为时间间隔较短或难以手动启动/停止记录的场景而设计。如需设置持续时间更长的记录,请使用 Android Studio 中的性能剖析器界面。

简而言之,这种方式适合app冷启动,或者短时间内的方法记录trace。

public class TraceMethodUtils {/*** 适合于非常精确的记录,某个具体函数的耗时分析** profiler cpu 中instrument模式,会从开始一直记录方法/cpu 使用情况,对性能影响大。*/public static void  startTrack(String tracFileName){Debug.startMethodTracing(fixTraceFileName(tracFileName));}/***  在android 5.0 以后使用,间隔时间微妙 **  profiler cpu 中sample模式,系统间隔us 周期性记录调用栈,对性能影响小* @param tracFileName*/public static void startSampleTrack(String tracFileName){//1000us=1ms 周期性记录一次Debug.startMethodTracingSampling(fixTraceFileName(tracFileName),0,1000);}private static String fixTraceFileName(String tracFileName){if (!TextUtils.isEmpty(tracFileName)){tracFileName=tracFileName.endsWith(".trace")?tracFileName:tracFileName+".trace";tracFileName=new StringBuilder().append(System.currentTimeMillis()).append("_").append(tracFileName).toString();}else{tracFileName=new StringBuilder().append(System.currentTimeMillis()).append(".trace").toString();}return tracFileName;}/*** 结束跟踪*/public static void stopTrack(){Debug.stopMethodTracing();}
}

冷启动/界面启动的分析,推荐使用startSampleTrack()。

这里,具体分析某个方法testPlay(), 执行需要记录的方法,记录如下所示:
在这里插入图片描述
以上文件在在DeviceFileExplorer 窗口中sdcard/android/data/package名目录,双击打开该trace文件,如下所示:
在这里插入图片描述
使用方式:首先选择需要查看的线程,进行双击进入。因testPlay()是在主线程中执行,因此在这里选择主线程:
在这里插入图片描述
Bottom UP窗口

用于观察某个方法中,调用其他若干方法的耗时占比,可更进一步筛选出耗时的具体位置,选择查看比例排前的几个方法。
比如,选中testPlay(),查看其内部的耗时方法占比:创建VideoView对象,耗时最大,3002us微妙=3ms毫秒。

在这里插入图片描述

Flame chat 火焰图窗口

用于倒置查看某个方法中调用若干方法的查看,很直观的看到方法调用情况与耗时情况。淡黄色的往往是需要关注的方法点,可优化点也是在这里。

在这里插入图片描述
Top Down窗口

可用于查看,该方法向下调用栈,也可以清楚看到接下来代码逻辑走向。也是按耗时排列。

在这里插入图片描述
使用总结: 打开trace文件后–>双击选择线程–>选择观察的方法–>Top Down窗口细化查看耗时方法–>Bottom UP窗口找到耗时所在点。

Trace 存储路径和sdcard 权限问题

简单来看下trace的保存路径逻辑:
在这里插入图片描述

发现,trace 是默认保存在sdcard/android/data/package名目录或者sdcard根目录中,因此必须要有sdcard读写权限。trace会自动补全.trace后缀名。

官方资料:https://developer.android.com/studio/profile/record-traces?hl=zh-cn#debug-api

资料参考

  • Android Studio 中 CPU Profiler 系统性能分析工具的使用:https://juejin.cn/post/7098548053136637983
  • https://juejin.cn/post/7024387231104106503
  • 基于AOP思想的Android方法耗时开源分析工具TimeTracer:https://www.paincker.com/time-tracer/
  • https://jishuin.proginn.com/p/763bfbd4c428
  • https://zhuanlan.zhihu.com/p/508526020
  • https://juejin.cn/post/7163522788781719559
  • 性能优化:https://www.jianshu.com/p/837ad55f3049

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RTT驱动框架分析01】-pin/gpio驱动分析

0gpio使用测试 LED测试 #define LED1_PIN GET_PIN(C, 1) void led1_thread_entry(void* parameter) {rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);while(1){rt_thread_delay(50); //delay 500msrt_pin_write(LED1_PIN, PIN_HIGH);rt_thread_delay(50); //delay 50…

MySQL之深入InnoDB存储引擎——物理文件

文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…

6-Linux的磁盘分区和挂载

Linux的磁盘分区和挂载 Linux分区查看所有设备的挂载情况 将磁盘进行挂载的案例增加一块磁盘的总体步骤1-在虚拟机中增加磁盘2- 分区3-格式化分区4-挂载分区5-进行永久挂载 磁盘情况查询查询系统整体磁盘使用情况查询指定目录的磁盘占用情况 磁盘情况-工作实用指令统计文件夹下…

Vue3搭建启动

Vue3搭建&启动 一、创建项目二、启动项目三、配置项目1、添加编辑器配置文件2、配置别名3、处理sass/scss4、处理tsx(不用的话可以不处理) 四、添加Eslint 一、创建项目 npm create vite 1.project-name 输入项目名vue3-vite 2.select a framework 选择框架 3.select a var…

关于前端框架vue2升级为vue3的相关说明

一些框架需要升级 当前(202306) Vue 的最新稳定版本是 v3.3.4。Vue 框架升级为最新的3.0版本,涉及的相关依赖变更有: 前提条件:已安装 16.0 或更高版本的Node.js(摘) 必须的变更:核…

C语言进阶——文件的打开(为什么使用文件、什么是文件、文件的打开和关闭)

目录 为什么使用文件 什么是文件 程序文件 数据文件 文件名 文件的打开和关闭 文件指针 打开和关闭 为什么使用文件 在之前学习通讯录时,我们可以给通讯录中增加、删除数据,此时数据是存放在内存中,当程序退出的时候,通讯…

【弹力设计篇】聊聊灾备设计、异地多活设计

单机&集群架构 对于一个高可用系统来说,为了提升系统的稳定性,需要以下常用技术服务拆分、服务冗余、限流降级、高可用架构设计、高可用运维,而本篇主要详细介绍下,高可用架构设计。容灾备份以及同城多活,异地多活…

OpenCV实现高斯模糊加水印

# coding:utf-8 # Email: wangguisendonews.com # Time: 2023/4/21 10:07 # File: utils.pyimport cv2 import PIL from PIL import Image import numpy as np from watermarker.marker import add_mark, im_add_mark import matplotlib.pyplot as plt# PIL Image转换成OpenCV格…

redis分布式锁

Redis 作者继续论述,如果对方认为,发生网络延迟、进程 GC 是在步骤 3 之后,也就是客户端确认拿到了锁,去操作共享资源的途中发生了问题,导致锁失效,那这不止是 Redlock 的问题,任何其它锁服务例…

Flowable-任务-脚本任务

定义 脚本任务(Script Task)是一种自动执行的活动。当流程执行到达脚本任务时,会执行相应的 脚本,完毕后继续执行后继路线。脚本任务无须人为参与,可以通过定义脚本实现自定义的业务逻辑。 图形标记 脚本任务显示为…

数据结构基础:3.单链表的实现。

单链表的介绍和实现 一.基本概念1.基本结构2.结构体节点的定义: 二.功能接口的实现0.第一个节点:plist1打印链表2创建一个节点3.头插4.头删5.尾插6.尾删7.查找8.在pos之前插入x9.在pos之后插入x10.删除pos位置11.删除pos的后一个位置12.链表释放 三.整体…

C语言每天一练----输出水仙花数

题目&#xff1a;请输出所有的"水仙花数" 题解&#xff1a;所谓"水仙花数"是指一个3位数,其各位数字立方和等于该数本身。 例如, 153是水仙花数, 因为153 1 * 1 * 1 5 * 5 * 5 3 * 3 * 3" #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h&g…

【自动化运维】Ansible常见模块的运用

目录 一、Ansible简介二、Ansible安装部署2.1环境准备 三、ansible 命令行模块3.1&#xff0e;command 模块3.2&#xff0e;shell 模块3.3&#xff0e;cron 模块3.4&#xff0e;user 模块3.5&#xff0e;group 模块3.6&#xff0e;copy 模块3.7&#xff0e;file 模块8&#xff…

【雕爷学编程】MicroPython动手做(10)——零基础学MaixPy之神经网络KPU

早上百度搜“神经网络KPU”&#xff0c;查到与非网的一篇文章《一文读懂APU/BPU/CPU/DPU/EPU/FPU/GPU等处理器》&#xff0c;介绍各种处理器非常详细&#xff0c;关于“KPU”的内容如下&#xff1a; KPU Knowledge Processing Unit。 嘉楠耘智&#xff08;canaan&#xff09;号…

找不到mfc140u.dll怎么解决

第一&#xff1a;mfc140u.dll有什么用途&#xff1f; mfc140u.dll是Windows操作系统中的一个动态链接库文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分。MFC是 C中的一个框架&#xff0c;用于构建Windows应用程序的用户界面和功能。mfc140u.dll包含了MFC库中…

杂谈项——关于我在bw上的见闻,以及个人对二次元游戏行业方面的前瞻

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家带来一点不一样的&#xff0c;首先先光速叠一下甲&#xff1a; 在此说明博主并不是一个什么都知道的大佬&#xff0c;只是一个普通的老二次元以及期望以后能…

HCIP重发布实验

目录 实验要求&#xff1a; 步骤一&#xff1a;拓扑设计IP地址规划 拓扑设计 R1 R2 R3 R4 发布路由 R1 R2 R3 R4 双向重发布 在R2和R4 上进行 R2 R4 检查R1 修改开销值选路 择优选择去4.0网段的路径 测试&#xff1a;​编辑 择优选择去32网段的路径 测试&…

短视频矩阵源码/系统搭建/源码

一、短视频矩阵系统开发需要具备以下能力 短视频技术能力&#xff1a;开发人员应具备短视频相关技术能力&#xff0c;如视频编解码、视频流媒体传输等。 大数据存储和处理能力&#xff1a;短视频矩阵系统需要处理大量的视频数据&#xff0c;因此需要具备大数据存储和处理的能力…

JavaScript快速入门:ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器

JavaScript快速入门&#xff1a;ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器 在当今丰富的网络环境中&#xff0c;处理 PDF 文档已成为企业和开发人员的必需品。ComPDFKit 是一款支持 Web 平台并且功能强大的 PDF SDK&#xff0c;开发人员可以利用它创建 PDF 查看器和编辑器&…

初探webAssembly | 京东物流技术团队

1 WebAssembly是什么&#xff1f; 一种运行在现代网络浏览器中的新型代码&#xff0c;并且提供新的性能特性和效果 W3C WebAssembly Community Group开发的一项网络标准&#xff0c;对于浏览器而言&#xff0c;WebAssembly 提供了一条途径&#xff0c;让各种语言编写的代码以接…