全面了解CPU Profiler:解读CPU性能分析工具的核心功能与用法
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
目录
- 一、导读
- 二、概览
- 三、使用
- 3.1 通过调用系统API
- 3.2 通过Android Studio
- 3.2.1 轨迹界面说明
- 3.2.2 Android Studio 抓取 App 启动的 trace 信息
- 四、trace文件分析
- 4.1 使用调用图表检查跟踪数据
- 4.2 Flame Chart
- 4.3 Top Down
- 4.4 Bottom Up
- 4.5 Events
- 五、优缺点
- 六、推荐阅读
一、导读
我们继续总结学习Android基础知识,温故知新。
工欲善其事必先利其器,我们要做性能优化,首先要掌握好相关工具。
二、概览
Traceview 是一个用于分析应用程序性能的工具,用来分析函数调用过程。
CPU Profiler 是 集成在Android Studio 3.2版本之后的Android Profiler工具当中,实时记录展示 App cpu消耗,用来替代Traceview。
都可以记录应用程序在运行过程中的各个方法(函数)的执行时间以及方法之间的调用关系。通过Traceview,开发者可以了解应用程序中哪些方法占用了较多的时间,从而找到性能瓶颈并进行优化。
还可以以图形方式显示方法的调用树,使开发者能够更直观地分析代码的执行流程。
常用于卡顿优化、启动优化、内存优化等。
这里我们要了解一下traceview 跟 cpu profile的区别,我们在新版的android studio中已经没有单独的traceview了,就是换成cpu profile,一样的。
开发者网站
三、使用
我们可以有两种方式来抓取相关信息。
3.1 通过调用系统API
开始:
Debug.startMethodTracingSampling(new File("ddd"), 0, 5000);
这样的话,我们就开始通过traceview来使用结束:
Debug.stopMethodTracing();
当调用该方法后,就会生产一个文件,
当文件生成后,存放位置 sd卡/Android/data/包名/files 目录下,
startMethodTracingSampling 是有几个重载的方法的,我们看下源码
/*** * tracePath – 文件名,或者传入具体的路径* bufferSize – 文件大小,默认8MB.* intervalUs – The amount of time between each sample in microseconds.*/startMethodTracingSampling(String tracePath, int bufferSize, int intervalUs) {VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs);
}
3.2 通过Android Studio
如下图所示,依次点击profile - cpu ,然后会跳转到 cpu界面,然后就可以进行录制了。
通过图2,我们可以看到这里有四个选项,我们分别介绍: 官网
-
Callstack Sample (Sample C/C++ Functions)
捕获应用的原生线程的采样跟踪数据。在内部,此配置使用 simpleperf 跟踪应用的原生代码。 -
System Trace (Trace System Calls:)
捕获非常翔实的细节,以便您检查应用与系统资源的交互情况。您可以检查线程状态的确切时间和持续时间、直观地查看所有内核的CPU瓶颈在何处,并添加需分析的自定义跟踪事件。 -
Java/Kotlin Method Trace (Trace Java Methods)
在运行时检测应用,从而在每个方法调用开始和结束时记录一个时间戳。系统会收集并比较这些时间戳,以生成方法跟踪数据,包括时间信息和 CPU 使用率。
请注意,与检测每个方法相关的开销会影响运行时性能,并且可能会影响分析数据;对于生命周期相对较短的方法,这一点更为明显。此外,如果应用在短时间内执行大量方法,则分析器可能很快就会超出其文件大小限制,因而不能再记录更多跟踪数据。
-
Java/Kotlin Method Sample (Sample Java Methods )
在应用的 Java 代码执行期间,频繁捕获应用的调用堆栈。分析器会比较捕获的数据集,以推导与应用的 Java 代码执行有关的时间和资源使用信息。基于采样的跟踪存在一个固有的问题,那就是如果应用在捕获调用堆栈后进入一个方法并在下次捕获前退出该方法,分析器将不会记录该方法调用。如果您想要跟踪生命周期如此短的方法,应使用插桩跟踪。
点击record开始记录,当应用交互,然后在完成时点击 Stop。性能分析器会自动在轨迹窗格中显示其跟踪信息,如下图所示。
3.2.1 轨迹界面说明
我们先对上图的每个区域做一下解释:
-
选定范围:确定需在轨迹窗格中检查所记录时间的哪一部分。当您首次记录轨迹时,CPU 性能分析器会自动在 CPU 时间轴上选择记录的完整长度。如需仅检查已记录的时间范围中的一部分的跟踪数据,请拖动突出显示区域的边缘。
-
“Interaction”部分:沿着时间轴显示用户互动和应用生命周期事件。
-
“Threads”部分:沿时间轴针对每一个线程显示线程状态活动(例如运行、休眠等)和调用图表(在 System Trace 中则为轨迹事件图表)。
使用鼠标和键盘快捷键在时间轴上导航。
双击线程名称,或在选中线程时按 Enter 键以展开或折叠线程。
选择某个线程即可在“Analysis”窗格中查看更多信息。 按住 Shift 或 Ctrl(Mac 上为 Command)可选择多个线程。
选择方法调用(或 System Trace 中的轨迹事件),以在“Analysis”窗格中查看更多信息。 -
“Analysis”窗格:就是标记 4 的那一片的整个区域,显示您选择的时间范围和线程/方法调用的跟踪数据。在此窗格中,您可以选择如何查看每个堆栈轨迹(使用“Analysis”标签页 ,下面第 5 个 ),以及如何测量执行时间(使用“Time reference”下拉菜单下面第 6 个)。
-
“Analysis”标签页:选择如何显示跟踪数据详细信息。如需详细了解各个选项,请参阅检查跟踪数据。
-
"Time reference"菜单:选择以下选项之一,以确定如何测量每次调用的时间信息(仅在示例/跟踪 Java 方法中受支持):
wall clock time : 程序执行时间,包括调用其他方法的时间
thread time: cpu执行时间
- 搜索框,可按函数、方法、类或软件包名称过滤跟踪数据。
3.2.2 Android Studio 抓取 App 启动的 trace 信息
如果我们要在应用一启动就记录CPU活动,需要单独配置一下:
- 依次选择 Run > Edit Configurations
- 选择 Profiling - 勾选 Start this recording on startup - 选 callstack sample(跟踪 Java 方法)- apply -ok
四、trace文件分析
不管通过那种方式,我们得到trace文件后,直接拖到 android studio里面打开即可。
CPU 性能分析器中的轨迹视图提供了多种方法查看来自所记录的轨迹的信息。
-
对于方法轨迹和函数轨迹,您可以直接在 Threads 时间轴中查看 Call Chart,并从 Analysis 窗格中查看 Flame Chart、Top Down、Bottom Up 和 Events 标签页。
-
对于调用堆栈帧,您可以查看代码中已执行的部分及其调用原因。
-
对于系统轨迹,您可以直接在 Threads 时间轴中查看 Trace Events,并从 Analysis 窗格中查看 Flame Chart、Top Down、Bottom Up 和 Events 标签页。
提示:检查 Threads 时间轴时,您可以使用以下快捷方式:
- 放大:按 W 或在按住 Ctrl 键的同时滚动鼠标滚轮(在 Mac 上,按住 Command 键)。
- 缩小:按 S 或在按住 Ctrl 键的同时向后滚动鼠标滚轮(在 Mac 上,按住 Command 键)。
- 向左平移:按 A 键或在按住空格键的同时向右拖动鼠标。
- 向右平移:按 D 键或在按住空格键的同时向左拖动鼠标。
- 展开或收起线程:双击线程名称,或在选中线程时按 Enter 键。
4.1 使用调用图表检查跟踪数据
举个例子,一个调用图表示例,展示了方法 D 的 Self 时间、Children 时间和 Total 时间。
4.2 Flame Chart
Flame Chart 标签页提供一个倒置的调用图表,用来汇总完全相同的调用堆栈。
将具有相同调用方顺序的完全相同的方法或函数收集起来,并在火焰图中将它们表示为一个较长的横条。
这样更方便您查看哪些方法或函数消耗的时间最多。不过,这也意味着,横轴不代表时间轴,而是表示执行每个方法或函数所需的相对时间。
4.3 Top Down
用于显示方法等调用列表。
如图 所示,在 Top Down 标签页中展开方法 A 的节点会显示它的被调用方,即方法 B 和 D。在此之后,展开方法 D 的节点会显示它的被调用方,即方法 B 和 C,依此类推。
Top Down 标签提供一些信息来显示每个调用所花的 CPU 时间:
- Self:方法或函数调用在执行自己的代码(而非被调用方的代码)上所花的时间,如图 1 中的方法 D 所示。
- Children:方法或函数调用在执行它的被调用方(而非自己的代码)上所花的时间,如图 1 中的方法 D 所示。
- Total:方法的 Self 时间和 Children 时间的总和。这表示应用在执行调用时所用的总时间,如图 1 中的方法 D 所示。
4.4 Bottom Up
Bottom Up 标签页用于按照占用的 CPU 时间由多到少(或由少到多)的顺序对方法或函数排序。您可以检查每个节点以确定哪些调用方在调用这些方法或函数上所花的 CPU 时间最多。
4.5 Events
“Events”表格列出了当前所选线程中的所有调用。
五、优缺点
运行时开销严重,整个代码运行都变得非常慢,因为traceview会抓取所有线程的所有函数的数据。
所有有可能带偏我们的优化方向。
比如有个方法xyz(),本身不耗时,但是加上traceview后,我们在文件里面发现它的耗时变长了,我们可能会错误的认为这个方法很耗时,然后花费精力在这个上面。
六、推荐阅读
Java 专栏
SQL 专栏
数据结构与算法
Android学习专栏
相关文章:

全面了解CPU Profiler:解读CPU性能分析工具的核心功能与用法
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、使用3.1 通过调用系统API3.2 通过Android Stu…...

rust format!如何转义{},输出{}?
在Rust中,如果你想要在字符串中包含花括号 {} ,你需要使用双花括号 {{}} 来进行转义。这是因为单个花括号 {} 在字符串中表示占位符,用于格式化字符串。 以下是一个示例: fn main() {let text "这是一个示例: {…...

真人AI写真的制作方法-文生图换脸
AI写真最近火起来了,特别是某款现象级相机的出现,只需要上传自己的照片,就能生成漂亮的写真照,这一产品再次带火了AI绘画。今天我就来分享一个使用Stable Diffusion WebUI制作真人AI写真的方法,不用训练,快…...

vscode如何包含第三方库
方法1:使用C Extension 在include 的 rapidjson的头文件时,vscode会提示找不到的问题 悬停,点击黄色提示 Edit "includePath" setting Include Path,输入rapidjson的include路径 /Users/xxx/workspaces/rapidjson-1.1.…...

【Docker】Docker安装Consul
文章目录 1. 什么是Consul2. Docker安装启动Consul 点击跳转:Docker安装MySQL、Redis、RabbitMQ、Elasticsearch、Nacos等常见服务全套(质量有保证,内容详情) 1. 什么是Consul Consul是HashiCorp公司推出的开源软件,提…...

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(20)-Fiddler精选插件扩展安装让你的Fiddler开挂到你怀疑人生
1.简介 Fiddler本身的功能其实也已经很强大了,但是Fiddler官方还有很多其他扩展插件功能,可以更好地辅助Fiddler去帮助用户去开发、测试和管理项目上的任务。Fiddler已有的功能已经够我们日常工作中使用了,为了更好的扩展Fiddler,…...

计算机top命令
top 快捷键 1 核心参数 1 1 参考资料 [1]. https://blog.csdn.net/weixin_45465395/article/details/115728520 [2].https://www.cnblogs.com/liushui-sky/p/13224762.html...

DevExpress WPF Tree List组件,让数据可视化程度更高!(二)
DevExpress WPF Tree List组件是一个功能齐全、数据感知的TreeView-ListView混合体,可以把数据信息显示为REE、GRID或两者的组合,在数据绑定或非绑定模式下,具有完整的数据编辑支持。 在上文中(点击这里回顾DevExpress WPF Tree …...

lc1074.元素和为目标值的子矩阵数量
创建二维前缀和数组 两个for循环,外循环表示子矩阵的左上角(x1,y1),内循环表示子矩阵的右下角(x2,y2) 两个for循环遍历,计算子矩阵的元素总和 四个变量,暴力破解的时间复杂度为O(…...

elementUi el-radio神奇的:label与label不能设置默认值
问题:最近项目遇到一个奇葩的问题:红框中列表的单选按钮无法根据需求设置默认选中,但是同样是设置开启状态的单选框可以设置默认状态 原因:开始同样是和开启/关闭状态一样也把红框中列表的默认值设置为数字模式,但是由…...

git仓库清理
关于git仓库的清理,主要就是清理git仓库里面的大的二进制文件。网上查了很多教程,很多都是用:git filter-branch.清理仓库中的大文件。 我尝试着本地测试了一下,发现是真慢呀。 方法一、git filter-branch step1:查…...

从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】【基础篇完结】
从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】 1 读写协程分离[v0.7] 添加一个Reader和Writer之间通信的channel添加一个Writer goroutineReader由之前直接发送给客户端改为发送给通信channel启动Reader和Writer一起工作 zinx/znet/co…...

python-爬虫作业
# -*- coding:utf-8 -*-Author: 董咚咚 contact: 2648633809qq.com Time: 2023/7/31 17:02 version: 1.0import requests import reimport xlwt from bs4 import BeautifulSoupurl "https://www.dygod.net/html/gndy/dyzz/" hd {user-Agent:Mozilla/4.0 (Windows N…...

vue3+ts+pinia整合websocket
文章目录 一. 目标二. 前置环境三. websocket通用模板 一. 目标 先有实时数据需要展示. 由于设备量极大且要对设备参数实时记录展示.axios空轮询不太适合. 选择websocket长连接通讯. 使用pinia原因是pinia具备共享数据性质.可以作为消息队列缓存数据,降低渲染压力.同时方便多…...

【微信小程序】保存多张图片到本地相册
<template><view class"container"><u-swiper :list"list" circular radius0 indicator indicatorModedot height950rpx></u-swiper><view class"btn btn2" click"saveFun">保存到相册</view><…...

Python Numpy入门基础(二)数组操作
入门基础(二) NumPy是Python中一个重要的数学运算库,它提供了了一组多维数组对象和一组用于操作这些数组的函数。以下是一些NumPy的主要特点: 多维数组对象:NumPy的核心是ndarray对象,它是一个多维数组对…...

【LeetCode每日一题】——1572.矩阵对角线元素的和
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 1572.矩阵对角线元素的和 四【题目描述】 给你一…...

牛客网Verilog刷题——VL55
牛客网Verilog刷题——VL55 题目答案 题目 请用Verilog实现4位约翰逊计数器(扭环形计数器),计数器的循环状态如下: 电路的接口如下图所示: 输入输出描述: 信号类型输入/输出位宽描述clkwireInput1系统…...

python中数据可视化
1.掷一个D6和一个D10 50000次的结果 die.py from random import randintclass Die:def __init__(self, num_sides6):self.num_sides num_sidesdef roll(self):return randint(1, self.num_sides) die_visual.py from die import Die from plotly.graph_objs import Bar, L…...

DASCTF 2023 0X401七月暑期挑战赛web复现
目录 <1> Web (1) EzFlask(python原型链污染&flask-pin) (2) MyPicDisk(xpath注入&文件名注入) (3) ez_cms(pearcmd文件包含) (4) ez_py(django框架 session处pickle反序列化) <1> Web (1) EzFlask(python原型链污染&flask-pin) 进入题目 得到源…...

go编译文件
1.编译go文件 go build [go文件]2.执行文件编译文件 ./demo [demo为go文件名称]...

Flowable-子流程-调用活动
目录 定义图形标记XML内容界面操作使用示例子流程设计子流程的XML内容主流程设计主流程的XML内容 视频教程 定义 调用活动是在一个流程定义中调用另一个独立的流程定义,通常可以定义一些通用的流程作为 这种调用子流程,供其他多个流程定义复用。这种子流…...

java 并发
目录 什么是线程?什么是进程?为什么要有线程?有什么关系与区别?什么是守护线程?如何创建、启动 Java 线程?线程池参数详细解释Callable接口和Future类偏向锁 / 轻量级锁 / 重量级锁synchronized 和 java.ut…...

【MySQL】DDL和DML
4,DDL:操作数据库 我们先来学习DDL来操作数据库。而操作数据库主要就是对数据库的增删查操作。 4.1 查询 查询所有的数据库 SHOW DATABASES; 运行上面语句效果如下: 上述查询到的是的这些数据库是mysql安装好自带的数据库,我们以后不要操…...

使用python框架FastAPI
中文文档 Python ORM之SQLAlchemy Fastapi大型项目目录规划 SQL数据库操作 依赖项Depends 待看 和APIRouter from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmakerapp FastAPI()SQ…...

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位
效果:点击表格可实现选中地图点位,删除按钮点击可删除对应点位并且重新绘制线段,点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 完整的组件代码如下 文件名称为: leafletMakePointYt <!--* Descripti…...

ChatGPT辅助写论文:提升效率与创造力的利器
写作是人类最重要的交流方式之一,也是学术研究中不可或缺的环节。然而,写作并不是一件容易的事情,尤其是对于科研人员来说,他们需要花费大量的时间和精力来撰写高质量的论文,并且面临着各种各样的挑战,如语…...

面试攻略,Java 基础面试 100 问(六)
JAVA 泛型 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本 质是参数化类型,也就是说所操作的数据类型被指定为一个参数。比如我们要写一个排序方法, 能够对整型数组、字符串数组甚至其他任何类型的…...

图解系列 DNS查找过程和DNS缓存
DNS 充当地址簿。它将人类可读的域名 (google.com) 转换为机器可读的 IP 地址 (142.251.46.238)。 开局一张图 来自:https://xiaolishen.medium.com/the-dns-lookup-journey-240e9a5d345c 寻址流程 查询浏览器缓存:当你输入一个域名后,浏览…...

《吐血整理》高级系列教程-吃透Fiddler抓包教程(21)-如何使用Fiddler生成Jmeter脚本-上篇
1.简介 我们知道Jmeter本身可以录制脚本,也可以通过BadBoy,BlazeMeter等工具进行录制,其实Fiddler也可以录制Jmter脚本(而且有些页面,由于安全设置等原因,使用Jmeter直接无法打开录制时,这时就…...