全面了解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) 进入题目 得到源…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...