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

news2024/12/26 20:52:00

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.coloradmin.cn/o/792277.html

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

相关文章

Python小练习实践

在交互模式下,可以不写print;默认调用 print(repr(a)) 文件模式,必须写print。 If语句 Input语句,返回的是字符串 len(),长度 小练习: 输入一个自己的生日月份 写个if 和else 判断一下当月是否是你的生日…

celery----异步发送短信

1.目录结构 -celery.py --------必须叫这个名字 放定时任务、里面实例化得到app对象 -home_task.py和user_task.py. ----------就是针对不同app的任务文件 2.各文件的内容 celery.py from datetime import timedeltafrom celery import Celery from celery.schedu…

PLL设计-仿真

线性相位裕锁相环模型 out都代表噪声,PFDCP的gain是Icp/2π,LF的传输函数是,VCO传输函数是,分频器增益是1/N 首先不考虑噪声模型 阶跃响应-查看建立时间,下面两条线是上面两条线减1V后的结果,方便查看。 放大上图,输入…

支持向量机(SVM)---代码实现

# coding: utf-8## 感知器模型流程 """1.初始化w, b2.遍历所有训练数据集中选出的误分类点&#xff1a;2.1.如果y ! sign(wxb) 或者 y*(wxb) < 0 则为误分类点2.2 根据误分类点计算&#xff1a;w_new w_old -alpha * 对w的梯度&#xff0c; b_new b_old - …

共聚焦显微镜在光学膜片表面微结构测量中的应用

在当前的液晶显示器行业&#xff0c;TFT液晶面板因其显示反应速度更快更适用于动画及显像显示的特点而得到广泛应用。作为配套组件的背光显示模组&#xff0c;为其供应充足且分布均匀的光源亮度&#xff0c;使得液晶面板的显像功能能够正常工作。液晶面板消费需求的不断增长带动…

【vue3】获取字典数据,封装为公共方法

前言: 后台项目中基本上都有字典管理页面,Vue封装字典数据的主要目的是为了方便数据的管理和使用 不管在哪个页面使用下拉框,el-select的options数据源需要通过调用接口获取到,不同的数据源调用不同的接口,引入和使用都是不小的工作量,如果使用字典数据管理,不管同个页…

(打造透明屏展厅全攻略)如何打造透明OLED显示屏展厅?

透明OLED显示屏是一种具有透明度的显示屏幕&#xff0c;可以在不使用时完全透明&#xff0c;从而实现空间与显示的完美融合。在展厅设计中&#xff0c;透明OLED显示屏可以带来全新的视觉体验&#xff0c;使展品更加生动、立体&#xff0c;展示效果更佳。下面是打造透明OLED显示…

Hi3536网络应用调优

目录 1. 为什么UDP接收或发送会丢包? 2. 使用 socket 接口时&#xff0c;如何正确工作在非阻塞模式下&#xff1f; 3. TOE 使能及使用注意事项 4. TOE 模式下使用 socket 接口时的注意事项 1. 为什么UDP接收或发送会丢包? 用户态应用程序在接收 UDP 数据时&#xff0…

什么是SVM算法?硬间隔和软间隔的分类问题

SVM全称是supported vector machine(支持向量机)&#xff0c;即寻找到一个超平面使样本分成两类&#xff0c;并且间隔最大。 SVM能够执行线性或⾮线性分类、回归&#xff0c;甚至是异常值检测任务。它是机器学习领域最受欢迎的模型之一。SVM特别适用于中小型复杂数据集的分类。…

梯度提升树的基本思想

目录 1. 梯度提升树 VS AdaBoost 2. GradientBoosting回归与分类的实现 2.1 GradientBoosting回归 2.2 GradientBoosting分类 1. 梯度提升树 VS AdaBoost 梯度提升树&#xff08;Gradient Boosting Decision Tree&#xff0c;GBDT&#xff09;是提升法中的代表性算法&#…

kali中的一些工具简单使用dirb、netdiscover、ffuf、nmap、sqlmap、hydra、msfconsole

kali渗透常用工具 dirbnetdiscover介绍 ffuf介绍 nmap介绍 sqlmaphydra介绍 msfconsolemsfconsole上线windows dirb dirb <目标URL> <字典文件> [选项] <目标URL>&#xff1a;要扫描的目标URL&#xff0c;例如&#xff1a;http://example.com。 <字典文件…

nodeiis部署步骤

用nodejs写了一个express框架的接口&#xff0c;记录一下它如何在iis上发布部署 nodeiis部署步骤 第一步 安装nodejs 安装步骤&#xff1a;略确认安装结果&#xff1a;在cmd执行命令node -v效果图 第二步 安装iisnode 下载地址&#xff1a;iisnode下载地址&#xff08;htt…

Sentinel针对IP限流

改造限流策略的针对来源选项 import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class Senti…

php 中文字符串反转【字符串】

场景&#xff1a;英文字符串反转 使用 方法 strrev($str) ,但是中文字符串怎么反转呢&#xff1f; 代码 /*** 多字符 字符串反转* param string $string 字符串* param string $encoding 编码* php > 7.4 否则需要实现 mb_str_split 多字符变成字符串*/ function mb_str…

【雕爷学编程】Arduino动手做(88)---水流量传感器模块4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

Centos7安装cloudreve+onlyoffice

Centos7安装cloudreveonlyoffice 1.安装onlyoffice 1.1 安装onlyoffice镜像 docker run -i -t -d -p 801:80 --restartalways -e JWT_ENABLEDfalse --name onlyoffice \-v /home/xxx/important_onlyoffice/logs:/var/log/onlyoffice \-v /home/xxx/important_onlyoffice/dat…

Linux搭建Promtail + Loki + Grafana 轻量日志监控系统

一、简介 日志监控告警系统&#xff0c;较为主流的是ELK&#xff08;Elasticsearch 、 Logstash和Kibana核心套件构成&#xff09;&#xff0c;虽然优点是功能丰富&#xff0c;允许复杂的操作。但是&#xff0c;这些方案往往规模复杂&#xff0c;资源占用高&#xff0c;操作苦…

可视化时序输入与输出|python

请帮我生成可视化图的python代码&#xff0c;输入是xxx变量&#xff0c;输出是xxx变量&#xff0c;横坐标是时间&#xff0c;输入用蓝线表示&#xff0c;输出用黄线表示&#xff0c;然后输入和输出在时间维度上是分别一个在前&#xff0c;一个在后。 import matplotlib.pyplot…

安全狗深度参与编写的《云原生安全配置基线规范》正式发布!

7月25日&#xff0c;由中国信息通信研究院、中国通信标准化协会主办的2023可信云大会在北京顺利开幕。 作为国内云原生安全领导厂商&#xff0c;安全狗受邀出席此次活动。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a;安全狗&#xff09;成立于2013年&#xff0c…

《算法竞赛·快冲300题》每日一题:“凹”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 凹…