type
status
date
slug
summary
tags
category
icon
password
火焰图是什么?
虽然这篇文章只是准备介绍一些常见的Slice,帮助初学者更好的理解火焰图,但是我认为还是有必要在这里简单介绍一下火焰图:
火焰图(Flame Chart)是一种性能分析可视化工具。它以时间为横轴,调用栈深度为纵轴,用不同颜色的矩形块展示程序运行时各方法的执行时间和调用关系。
火焰图的主要特点:
- 横轴代表时间——从左到右显示程序执行的时间线
- 纵轴代表调用栈深度——越往上调用层级越深
- 矩形块的宽度——表示方法执行的耗时
- 颜色区分——不同颜色代表不同的线程、进程或方法类型
开发者可以通过火焰图快速识别性能瓶颈,找出最耗时的方法调用,进行针对性优化。
Perfetto 示例:
Perfetto 是 Google 开发的性能分析工具,可以生成详细的火焰图。你可以访问以下示例查看实际效果:Perfetto UI - 示例火焰图
打开火焰图后,你可以看到如下的样式
下边我们来分别介绍一下火焰图视角,双端的App常规运行过程以及常见Slice含义:
一、火焰图的基本视角
在分析性能问题时,火焰图提供了多个观察维度:
- 时间轴视角:横向查看程序执行的完整时间线,识别哪些时间段最耗时
- 调用栈视角:纵向查看方法调用的层级关系,找出深层调用链
- 线程视角:区分不同线程的工作负载,识别主线程卡顿或后台线程竞争
- 热点视角:通过矩形块宽度快速定位最耗时的方法或系统调用
二、Android App 常规运行过程与常见 Slice
从火焰图的视角来看,一个 Android App 的典型运行过程可以分为以下几个阶段:
🔷 阶段 1:应用启动与初始化
当用户点击应用图标时,系统首先会通过
zygote 进程 fork 出新的应用进程。在火焰图中,你会看到:bindApplication- 应用进程与 ActivityManagerService 建立连接
makeApplication- Application 对象的创建和初始化
activityStart→activityResume- 首个 Activity 的启动流程
这个阶段会有大量的 Binder 通信(
binderTransaction),因为应用需要与系统服务频繁交互。🔷 阶段 2:UI 渲染准备
Activity 进入 Resume 状态后,开始准备渲染 UI。火焰图中会出现:
inflate- 解析 XML 布局文件
performTraversals- 开始 View 树的遍历
measure→layout→draw- View 的测量、布局、绘制三大流程
VSync- 等待垂直同步信号
🔷 阶段 3:帧渲染循环(主线程 + RenderThread)
应用进入稳定运行状态后,每一帧的渲染都会在火焰图中呈现为一个完整的周期:
主线程(UI Thread):
Choreographer#doFrame- 帧渲染的核心入口,理想情况下每 16.6ms 触发一次(60fps)
deliverInputEvent/dispatchInput- 处理用户触摸事件
animation/animator- 执行动画
performTraversals- 再次遍历 View 树,更新需要重绘的部分
RenderThread(渲染线程):
RenderThread#doFrame- RenderThread 接管渲染任务
drawFrame- 构建绘制命令
issueDrawCommands- 向 GPU 发送绘制指令
eglSwapBuffers- 交换前后缓冲区,将内容显示到屏幕
GPU Completion- 等待 GPU 完成渲染
在这个过程中,主线程和 RenderThread 是并行工作的。你会在火焰图中看到它们在不同的轨道上同时执行。
🔷 阶段 4:列表滚动(RecyclerView 场景)
当用户滑动列表时,火焰图会显示密集的渲染活动:
RecyclerView#onBindViewHolder- 频繁出现,绑定数据到可见的 item
RecyclerView#layoutChildren- 重新布局子 View
GapWorker- 后台预加载即将显示的 item
Choreographer#doFrame- 持续的帧渲染
如果滑动不流畅,你会看到某些帧的
doFrame 超过 16.6ms,这就是丢帧。🔷 阶段 5:后台任务与 I/O 操作
应用运行过程中,后台线程会处理各种任务。在火焰图的其他线程轨道上,你会看到:
ThreadPoolExecutor- 线程池执行的任务
Dispatchers.IO- Kotlin 协程的 I/O 操作
sqlite/sqliteQuery- 数据库查询
read/write- 文件 I/O
binderTransaction- 与系统服务的跨进程通信
⚠️ 警告信号:如果这些操作出现在主线程轨道上,说明存在严重的性能问题!
🔷 阶段 6:垃圾回收(GC)
火焰图中会周期性出现 GC 相关的 Slice:
Background concurrent copying GC- 后台并发 GC,对性能影响较小
Pause Young/Pause Old- STW(Stop-The-World)类型的 GC,会暂停应用执行
如果 GC 过于频繁或暂停时间过长,说明存在内存抖动或内存泄漏。
🔷 阶段 7:系统服务的协同工作
在火焰图的系统进程轨道上,你会看到:
SurfaceFlinger- 负责屏幕合成,将所有应用的 Surface 合成到屏幕上
ActivityManager- 管理 Activity 生命周期
WindowManager- 管理窗口显示
这些系统服务通过
binderTransaction 与应用进程通信,协调整个系统的运行。📊 如何读懂这个流程
在 Perfetto 或其他火焰图工具中:
- 横向看时间线:从左到右观察应用启动 → UI 渲染 → 用户交互 → 后台任务的完整流程
- 纵向看调用栈:点击某个 Slice,查看它的父子调用关系
- 跨轨道看协作:主线程、RenderThread、后台线程、系统服务如何配合工作
- 关注宽度异常的 Slice:它们就是性能瓶颈
下面我们详细介绍各个阶段中常见 Slice 的具体含义:
🟦 1. 页面启动(Activity 启动)
这个阶段涵盖了从用户点击图标到页面完全可交互的整个过程。
关键 Slice:
activityStart- Activity 启动的开始标记
activityResume- Activity 进入前台可见状态
activityPause- Activity 失去焦点
activityIdle- Activity 完成所有初始化,进入空闲状态
bindApplication- 应用进程绑定到 ActivityManagerService
makeApplication- Application 对象创建
inflate- XML 布局文件解析和 View 对象创建
launchingActivity- 系统层面的 Activity 启动流程
RelayoutWindow- 窗口重新布局
项目中的自定义埋点:
K_onCreate_I- onCreate 生命周期埋点
K_onStart_I- onStart 生命周期埋点
K_onResume_I- onResume 生命周期埋点
K_finishApm_I:ApmTracker- APM 性能监控完成标记
性能优化关注点:
如果
inflate 耗时过长,考虑使用异步 inflate 或减少布局层级;如果 bindApplication 到 activityResume 之间时间过长,检查 Application 初始化和 onCreate 中的同步操作。🟦 2. UI 渲染(主线程 + RenderThread)
Android 的 UI 渲染分为主线程的测量/布局/绘制和 RenderThread 的 GPU 渲染两个阶段。
主线程渲染 Slice:
Choreographer#doFrame- 帧渲染的核心入口,每 16.6ms(60fps)触发一次
performTraversals- View 树的遍历,包含 measure、layout、draw 三大流程
executeTraversal- 执行遍历的实际操作
ViewRootImpl#performTraversals- ViewRootImpl 层面的遍历
deliverInputEvent- 输入事件分发
InputDispatcher- 系统输入事件调度
dispatchInput- 输入事件派发到具体 View
RenderThread 渲染 Slice:
RenderThread#doFrame- RenderThread 的帧处理
drawFrame- 绘制一帧
flushLayers- 刷新图层到 GPU
issueDrawCommands- 发送绘制命令到 GPU
eglSwapBuffers- 交换前后缓冲区,显示到屏幕
GPU Completion- GPU 完成渲染
动画相关:
animation- 动画执行
animator- Animator 动画
updateViewHierarchy- 更新 View 层级
View#draw- View 的绘制方法
性能优化关注点:
如果
Choreographer#doFrame 超过 16ms,说明丢帧;如果 performTraversals 耗时长,检查 measure/layout 复杂度;如果 eglSwapBuffers 等待时间长,说明 GPU 过载或过度绘制。🟦 3. View 测量和布局
这是 UI 渲染流程中的前两个阶段,决定了每个 View 的大小和位置。
关键 Slice:
measure- 测量阶段总体标记
onMeasure- 每个 View 的测量方法
performMeasure- 执行测量流程
layout- 布局阶段总体标记
onLayout- 每个 ViewGroup 的布局方法
performLayout- 执行布局流程
requestLayout- 请求重新布局
性能优化关注点:
频繁的
requestLayout 会导致重复测量和布局;嵌套过深的 ViewGroup(如多层 LinearLayout)会导致多次 measure;使用 ConstraintLayout 可以减少布局层级。🟦 4. RecyclerView / ListView
列表是 App 中最常见的 UI 组件,其性能直接影响用户体验。
关键 Slice:
RecyclerView#onBindViewHolder- 绑定数据到 ViewHolder
RecyclerView#onCreateViewHolder- 创建新的 ViewHolder
RecyclerView#layoutChildren- 布局子 View
recycler#bind- 回收池绑定操作
recycler#prefetch- 预取机制,提前创建/绑定即将显示的 item
GapWorker- RecyclerView 的后台预加载工作线程
性能优化关注点:
如果
onBindViewHolder 耗时长,避免在其中进行复杂计算或 I/O 操作;如果 onCreateViewHolder 频繁出现,检查 RecycledViewPool 配置;启用 setItemViewCacheSize 和预取机制可以改善滑动流畅度。🟦 5. I/O 与 Binder 通信
I/O 操作和跨进程通信是常见的性能瓶颈。
Binder 相关 Slice:
binderTransaction- Binder 事务
binderCallback- Binder 回调
transact- Binder 调用
I/O 相关 Slice:
read- 文件读取
write- 文件写入
FileSystem#read- 文件系统读操作
FileSystem#open- 打开文件
sqlite- SQLite 数据库操作
sqliteQuery- SQL 查询
cursorWindow- Cursor 数据窗口操作
系统调用:
epoll_wait- 等待 I/O 事件
futex- 线程同步原语
性能优化关注点:
主线程中出现
read、write、sqlite 说明存在主线程 I/O,应移到后台线程;频繁的 binderTransaction 可能导致跨进程通信开销过大。🟦 6. 线程池与协程
Android 中的并发编程工具。
关键 Slice:
ForkJoinPool- Fork/Join 框架
ThreadPoolExecutor- 线程池执行器
AsyncTask- 异步任务(已废弃)
HandlerThread- 带 Looper 的后台线程
Looper- 消息循环
JobScheduler- 系统任务调度
WorkManager- 后台任务管理
Dispatchers.IO- Kotlin 协程 IO 调度器
Dispatchers.Default- Kotlin 协程默认调度器
性能优化关注点:
合理配置线程池大小,避免线程数过多导致上下文切换;使用协程可以减少线程创建开销。
🟦 7. GC(垃圾回收)
GC 会暂停应用执行,是卡顿的常见原因。
关键 Slice:
Background concurrent copying GC- 后台并发复制 GC
Concurrent mark sweep- 并发标记清除
Concurrent mark- 并发标记阶段
Concurrent sweep- 并发清除阶段
Pause Young- 年轻代 GC 暂停
Pause Old- 老年代 GC 暂停
HeapTrim- 堆内存整理
TrimHeap- 堆内存裁剪
项目中的自定义标记:
G_onTrimMemory- 内存裁剪回调
GC_YoungGeneration- 年轻代 GC
GC_Concurrent- 并发 GC
性能优化关注点:
频繁的 GC 说明内存抖动,检查是否有大量临时对象创建;
Pause 类型的 GC 会导致明显卡顿。🟦 8. 系统服务
Android 系统服务的调用。
关键 Slice:
SurfaceFlinger- 屏幕合成服务
HWUI- 硬件加速 UI 渲染
VSync- 垂直同步信号
performSurfaceTransaction- Surface 事务
WindowManager- 窗口管理服务
ActivityManager- Activity 管理服务
PackageManager- 包管理服务
zygote64- 应用进程孵化器
dex2oat- DEX 到 OAT 编译
dexopt- DEX 优化
性能优化关注点:
首次安装或系统升级后的
dex2oat 会导致应用启动变慢;频繁的 WindowManager 调用可能影响 UI 响应。三、iOS App 常规运行过程与常见 Slice
🟦 1. 页面启动与生命周期
iOS 的页面生命周期与 Android 类似,但使用不同的方法名。
关键 Slice:
-[UIApplication _run]- UIApplication 运行循环
-[UIViewController viewDidLoad]- 视图加载完成
-[UIViewController viewWillAppear]- 视图即将出现
-[UIViewController viewDidAppear]- 视图已经出现
-[UIViewController viewWillDisappear]- 视图即将消失
applicationDidFinishLaunching- 应用启动完成
applicationWillEnterForeground- 应用即将进入前台
loadView- 加载视图
performLayout- 执行布局
项目中的自定义埋点:
PageStart- 页面启动
PageAppear- 页面出现
LoadView- 视图加载
性能优化关注点:
避免在
viewDidLoad 中执行耗时操作;将重量级初始化延迟到 viewDidAppear 之后。🟦 2. Runloop(主线程事件循环)
Runloop 是 iOS 主线程的核心机制,卡顿分析的关键。
关键 Slice:
kCFRunLoopBeforeTimers- 即将处理 Timer
kCFRunLoopBeforeSources- 即将处理 Source
kCFRunLoopBeforeWaiting- 即将进入休眠
kCFRunLoopAfterWaiting- 刚从休眠中唤醒
kCFRunLoopExit- 退出 Runloop
dispatch_main- 主队列任务
dispatch_async- 异步任务分发
mach_msg- Mach 消息传递
性能优化关注点:
如果
kCFRunLoopBeforeSources 到 kCFRunLoopBeforeWaiting 之间时间过长,说明主线程有耗时操作;监控 Runloop 状态可以实现卡顿检测。🟦 3. Core Animation 渲染
iOS 的渲染框架,负责所有动画和屏幕更新。
关键 Slice:
CA::Transaction::commit- Core Animation 事务提交
CA::Render::Frame- 渲染一帧
CA::Display::DisplayLink- 显示链接(类似 Android 的 Choreographer)
prepareCommit- 准备提交
commit- 提交渲染
render- 渲染操作
layoutSubviews- 布局子视图
drawRect:- 自定义绘制
UIRenderingServer- UI 渲染服务
常见卡顿点:
CA::Transaction::commit- CPU 到 GPU 的数据传输和同步
presentation update- 呈现更新
CA::Render::Server- 渲染服务器处理
性能优化关注点:
如果
CA::Transaction::commit 耗时长,检查 layer 数量和复杂度;避免在 drawRect: 中进行复杂绘制;使用 shouldRasterize 可以缓存复杂 layer。🟦 4. AutoLayout / SwiftUI
iOS 的布局系统。
AutoLayout Slice:
-[UIView _layoutSubviews]- 布局子视图
AutoLayout- 自动布局计算
layoutEngine- 布局引擎
SwiftUI Slice:
SwiftUI.Update- SwiftUI 更新
SwiftUI.Render- SwiftUI 渲染
SwiftUI.Body- SwiftUI body 计算
性能优化关注点:
复杂的 AutoLayout 约束会导致计算耗时;减少约束数量或使用 frame 布局可以提升性能;SwiftUI 的 body 应尽量轻量。
🟦 5. TableView / CollectionView
iOS 的列表组件。
关键 Slice:
cellForRowAtIndexPath:- 获取 cell
heightForRowAtIndexPath:- 计算行高
willDisplayCell:- cell 即将显示
layoutSubviews- cell 布局子视图
reloadData- 重新加载数据
performBatchUpdates- 批量更新
性能优化关注点:
缓存 cell 高度避免重复计算;在
cellForRowAtIndexPath: 中避免耗时操作;使用 estimatedRowHeight 可以提升加载速度。🟦 6. I/O 与系统调用
iOS 的文件和网络操作。
关键 Slice:
read- 读取
write- 写入
fsync- 文件同步
open- 打开文件
close- 关闭文件
SQLITE- SQLite 数据库
URLSession- 网络请求
CFNetwork- Core Foundation 网络
mach_msg_trap- Mach 消息陷阱
futex_wait- 线程等待
性能优化关注点:
主线程中出现 I/O 操作应移到后台队列;使用异步 I/O 避免阻塞。
🟦 7. Swift / Objective-C 运行时
语言层面的性能开销。
关键 Slice:
swift_release- Swift 对象释放
swift_retain- Swift 对象引用计数增加
objc_msgSend- Objective-C 消息发送
objc_retain- ObjC 引用计数增加
objc_release- ObjC 引用计数减少
objc_autoreleasePoolPop- 自动释放池清空
性能优化关注点:
频繁的 retain/release 说明对象生命周期管理不当;过多的
objc_msgSend 可能是动态派发导致。🟦 8. 内存管理
iOS 的内存分配和释放。
关键 Slice:
malloc- 内存分配
free- 内存释放
zone_malloc- 内存区域分配
vm_allocate- 虚拟内存分配
vm_deallocate- 虚拟内存释放
dirty_pages- 脏页(内存压力指标)
性能优化关注点:
频繁的 malloc/free 说明内存抖动;监控 dirty_pages 可以预防内存警告。
四、总结
通过理解这些常见的 Slice,你可以:
- 快速定位性能瓶颈:在火焰图中识别耗时的关键路径
- 针对性优化:根据 Slice 类型选择合适的优化策略
- 建立性能基线:对比不同版本的 Slice 耗时,量化优化效果
- 跨平台理解:掌握 Android 和 iOS 的性能特征,进行双端对比分析
在实际分析中,建议结合具体业务场景,关注那些占比最大、出现最频繁的 Slice,优先优化收益最高的部分。
- Author:akinIan
- URL:blog.akinaustin.space/article/2b4e7ea2-ebf7-8059-9825-c6bdd4bcd281
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!




