38、性能优化工具:Simpleperf、Traceview、Method Tracing、CPU Profiler
性能优化,说白了就是跟时间赛跑。
你写的代码跑得够快吗?卡顿到底卡在哪?CPU 是不是在空转?这些问题,光靠猜是没用的。我见过太多开发同学,凭感觉说“这里慢”,结果一测,瓶颈在别处。
所以,工具就是我们的眼睛。今天我把四个最常用的性能工具掰开揉碎讲清楚:Simpleperf、Traceview、Method Tracing、CPU Profiler。它们各有侧重,但组合起来,能覆盖 90% 的性能问题。
38.1 工具概览:选对工具,事半功倍
先给你一张总览图,心里有个谱。
嗯,这张图基本把四个工具的定位说清楚了。下面我一个个展开讲。
38.2 Simpleperf:底层性能分析的瑞士军刀
Simpleperf 是我个人最常用的工具。为什么?因为它基于 Linux 内核的 perf_event,能直接读取 CPU 硬件计数器。这意味着你可以看到缓存未命中、分支预测失败、指令周期这些底层指标。
我记得有一次,一个视频编解码模块在低端机上卡顿严重。用 CPU Profiler 看,只看到某个 native 函数占用高,但不知道原因。换成 Simpleperf 一看——L1 数据缓存未命中率高达 40%。原来是内存访问模式不连续,导致 CPU 一直在等数据。调整数据结构后,性能直接翻倍。
38.2.1 基本用法
# 采样 CPU 周期,持续 10 秒
simpleperf record -p <pid> -e cpu-cycles -f 1000 --duration 10 -o perf.data
# 生成报告
simpleperf report -i perf.data --sort comm,dso,symbol
这里 -f 1000 表示每秒采样 1000 次。采样频率越高,数据越精确,但文件也越大。我个人习惯先用 1000 试跑,如果热点不明显再提高到 4000。
38.2.2 常用事件
| 事件名称 | 含义 | 典型场景 |
|---|---|---|
| cpu-cycles | CPU 时钟周期 | 通用性能分析 |
| instructions | 执行的指令数 | 计算密集型任务 |
| cache-misses | 缓存未命中次数 | 内存访问优化 |
| branch-misses | 分支预测失败次数 | 条件分支优化 |
simpleperf list 可以查看当前设备支持的所有事件。不同芯片(骁龙、天玑、麒麟)支持的事件略有差异。
38.3 Traceview:方法调用时间的可视化利器
Traceview 是 Android SDK 自带的工具,现在已经集成到 Android Studio 的 Profiler 里了。它的核心能力是展示方法调用的时间线——哪个方法调用了哪个方法,花了多少时间,一目了然。
不过说实话,Traceview 有个缺点:它基于 Dalvik/ART 的 Trace 日志,需要开启 Debug 模式。这意味着它不适合线上环境。我一般只在开发阶段用。
38.3.1 生成 Trace 文件
// 代码中手动开启
Debug.startMethodTracing("app_trace");
// ... 你的业务逻辑 ...
Debug.stopMethodTracing();
// 或者用 adb 命令
adb shell am profile start <package> /data/local/tmp/app_trace.trace
adb shell am profile stop <package>
生成的 .trace 文件可以用 Android Studio 的 Profiler 打开,或者用命令行工具 dmtracedump 转换成图形。
38.3.2 怎么看 Traceview 的图?
打开 Traceview 后,你会看到两个面板:
- 时间线面板(上半部分):每个线程的执行情况,彩色条代表方法调用。
- 分析面板(下半部分):按方法名、调用次数、总耗时、自身耗时排序。
我通常先看 自身耗时(Self Time) 排在前面的方法。这些是真正在干活的方法,而不是在调用别人。如果一个方法自身耗时很少,但总耗时很高,说明它在等子方法返回——这时候要考虑异步或者缓存。
38.4 Method Tracing:精准到微秒的方法级分析
Method Tracing 和 Traceview 有点像,但更底层。它直接记录每个方法的进入和退出时间戳,精度可以达到微秒级。
我曾经遇到一个诡异的问题:某个动画在 Android 12 上掉帧,但在 Android 11 上正常。用 Method Tracing 一抓,发现 View.onDraw() 里多了一个 Bitmap.createBitmap() 调用,耗时 3ms。为什么 Android 12 才出现?因为 Android 12 的渲染管线变了,导致这个调用触发了同步锁。去掉后,动画恢复流畅。
38.4.1 使用方式
// 使用 Debug 类
Debug.startMethodTracingSampling("method_trace", 1000, 100);
// 采样间隔 1000 微秒,每次采样 100 个样本
// ... 业务代码 ...
Debug.stopMethodTracing();
这里 startMethodTracingSampling 是采样模式,开销比全量 Tracing 小很多。如果你需要全量数据,用 startMethodTracing 即可,但文件会非常大——我见过一个 10 秒的 Trace 文件超过 500MB。
38.4.2 与 Traceview 的区别
| 特性 | Traceview | Method Tracing |
|---|---|---|
| 数据来源 | Dalvik/ART Trace 日志 | 直接记录方法进入/退出 |
| 精度 | 毫秒级 | 微秒级 |
| 开销 | 中等 | 较大(全量模式) |
| 适用场景 | 宏观调用链分析 | 精准定位耗时方法 |
38.5 CPU Profiler:Android Studio 的图形化利器
CPU Profiler 是 Android Studio 自带的工具,也是大多数开发者最先接触的性能工具。它把 Simpleperf、Traceview、Method Tracing 的能力整合到了一个图形界面里。
我个人觉得,CPU Profiler 最大的优点是 低门槛。你不需要记命令,点几下鼠标就能看到 CPU 使用率、线程状态、方法调用栈。适合快速定位问题。
38.5.1 三种记录模式
- Sampled(采样):定期采样调用栈,开销低,适合长时间监控。
- Instrumented(插桩):记录每个方法的进入/退出,精度高,但开销大。
- Edit Configuration(自定义):可以指定采样频率、事件类型等。
我一般先用 Sampled 模式跑一遍,看看整体 CPU 负载。如果发现某个方法可疑,再切到 Instrumented 模式做精准分析。
38.5.2 怎么看 CPU Profiler 的图?
打开 CPU Profiler 后,你会看到:
- CPU 使用率曲线:绿色是用户态,蓝色是内核态,橙色是中断处理。
- 线程时间线:每个线程的状态(运行中、可运行、休眠、等待 I/O)。
- 调用栈火焰图:方法调用关系,宽度代表耗时。
这里有个坑:CPU Profiler 在低端机上可能会影响性能。我遇到过在骁龙 660 设备上开启 Profiler 后,原本不卡的应用开始掉帧。所以,如果怀疑是 Profiler 本身导致的性能问题,换 Simpleperf 试试。
38.6 实战:一个完整的性能分析流程
光讲理论不行,我给你一个真实案例的流程。
场景:某社交 App 的 Feed 列表滑动卡顿。
- 第一步:CPU Profiler 快速扫描
打开 CPU Profiler,Sampled 模式,滑动列表 10 秒。发现主线程 CPU 使用率高达 80%,其中
ImageView.setImageDrawable()占用最高。 - 第二步:Method Tracing 精准定位
在
setImageDrawable前后加 Method Tracing,发现BitmapFactory.decodeStream()耗时 15ms。嗯,图片解码在主线程。 - 第三步:Simpleperf 深挖底层
用 Simpleperf 看缓存命中率,发现图片解码时 L2 缓存未命中率高达 30%。说明图片尺寸过大,导致 CPU 频繁从内存加载数据。
- 第四步:优化方案
图片解码移到子线程,使用 Glide 的
override()限制解码尺寸。优化后,主线程 CPU 使用率降到 20%,滑动流畅。
你看,四个工具各司其职,缺一不可。
38.7 避坑指南
最后,分享几个我踩过的坑:
- 不要在生产环境开 Method Tracing:文件太大,而且会拖慢系统。我曾经在线上开了一次,结果用户手机直接卡死重启。
- Simpleperf 需要 root 或 eng 版本:普通 user 版本可能无法访问硬件计数器。如果没 root,用
simpleperf stat的软件事件代替。 - CPU Profiler 的火焰图可能不准:采样模式有概率丢失短方法调用。如果发现某个方法总耗时很高但自身耗时很低,可能是采样偏差。
- Traceview 文件兼容性:不同 Android 版本生成的 .trace 文件格式不同。Android 10 以上的文件,最好用 Android Studio 4.0+ 打开。
性能优化没有银弹。工具只是辅助,关键还是理解你的代码在 CPU 上到底怎么跑的。多练、多测、多分析,慢慢就有感觉了。
公众号:蓝海资料掘金营,微信deep3321