第二章:性能度量指标——你到底该盯住哪个数?

做性能优化,最怕的是“凭感觉”。

我记得刚接手一个SDK接入项目时,大家只盯着帧率看——帧率一掉就觉得SDK有问题。结果排查了半天,发现是CPU占用率爆了,导致渲染线程饿死。从那以后,我定了个规矩:没有度量,就没有优化。

这一章,我们就把四个核心指标掰开揉碎。你不但要知道它们是什么,还得知道在什么场景下该盯哪一个。

2.1 CPU使用率——别被平均值骗了

CPU使用率,说白了就是你的代码占用了处理器多少时间片。这个指标我一般拆成两层来看:全局CPU占用率和本进程CPU占用率。

维度 关注点 典型阈值 监控方式
全局CPU 设备整体负载 超过80%需警惕 dumpsys cpuinfo
进程CPU 自身SDK消耗 超过20%需要优化 top / /proc/pid/stat
线程级CPU 具体哪个线程在吃 单线程持续>40% Traceview / Perfetto

我在项目中遇到过一个问题:某个广告SDK在后台进行图片预加载,CPU占用从5%飙到了60%。但它的上报周期是1分钟一次,平均下来只有15%。嗯,这里要注意:只看平均值,你会漏掉峰值。

我曾经踩过的坑:只用adb shell top看CPU总值,没留意是哪条线程在搞鬼。结果查了三天日志,最后发现是一个垃圾回收线程循环跑疯了。建议你直接拿Perfetto做线程级采样,一秒都不要偷懒。

2.2 内存占用——不是越少越好

内存指标最容易被误解。很多人觉得“内存占用越低越好”,其实不是。内存本来就是拿来用的,关键是不要泄漏,不要碎片化。

// 重点关注三个维度
1. PSS(Proportional Set Size):进程实际占用的物理内存
2. Java Heap:Dalvik/ART堆的已用大小
3. Native Heap:C/C++分配的内存

我个人习惯在接入SDK后,用adb shell dumpsys meminfo [包名]打一份快照,记录基线。之后每次版本迭代都对比这个基线。一旦PSS增长了超过10%,就要立即排查。

为什么我会强调这个?有一次我们接入一个推流SDK,上线第一周一切正常。一个月后,部分用户出现OOM崩溃。一查,是SDK内部缓存了视频帧数据,但释放逻辑有漏洞——画面分辨率变化时,旧帧没清掉。这就是典型的隐性增长。

场景 关注点 建议监测手段
冷启动 初始化时一次性分配 记录启动结束时的PSS
运行中 周期性垃圾回收 GC日志 + 大对象分配检查
退出/销毁 SDK是否释放所有资源 退出后PSS是否回到基线
一个实用技巧:在测试阶段,故意触发多次Full GC再取内存值,看看有没有“残留”——这是发现隐形泄漏的好办法。

2.3 帧率——别只看平均值,要看掉帧分布

帧率(FPS)是用户最直观能感受到的指标。但你可别傻傻盯着60FPS这个数字。

为什么?一个简单例子:你在1秒内前500ms卡了1帧(掉到30FPS),后500ms跑满了60帧。平均下来还是接近55FPS,看起来很美好。但用户感受就是“卡了一下”。

我建议你关注两个东西:帧分布直方图和掉帧堆栈。

  • 帧分布直方图:看有多少帧落在8ms、16ms、24ms、32ms以上。
  • 掉帧堆栈:在掉帧那一刻,主线程在做什么?
// 常用的帧监控工具
- Choreographer.FrameCallback(自己打桩)
- BlockCanary(卡顿定位)
- 系统自带的GPU渲染模式(开发者选项)

我记得有一次,某社交SDK在列表滑动时频繁掉帧。直方图显示大部分帧都在8ms以内,但每10帧会出现一个50ms的“毛刺”。一查堆栈,发现是SDK在访问本地数据库时走了主线程IO。这就是典型的“高帧率下的卡顿”——平均值好看,但体验差。

2.4 启动时间——首帧和首屏,不是一个概念

SDK接入后,最怕的就是拖慢App冷启动。你想想看,用户等了几秒才看到内容,第一印象就差了。

启动时间我习惯拆成两个阶段:

  1. 首帧时间:从Application.onCreate到第一个Activity的onResume完成。
  2. 首屏时间:用户看到完整内容的时间点。
阶段 SDK常见影响 优化方向
首帧 在onCreate中执行网络请求、数据库初始化 异步初始化、懒加载、ContentProvider优化
首屏 SDK等待服务端配置、加载广告素材 预缓存、按需加载、超时降级
一条硬规则:SDK初始化不得阻塞主线程超过200ms。超过这个数,用户就能感知到启动卡顿。我曾经把一个15ms的初始化操作从主线程移到了后台线程,首帧时间直接降了300ms。

2.5 把这些指标串起来

好了,现在你已经知道每个指标是什么了。但实际工作中,这些指标是相互关联的。我画了一张图,帮你理清它们之间的关系。

性能指标关联关系 CPU使用率 内存占用 帧率 启动时间 高CPU占用挤占渲染线程 启动时大量CPU运算 频繁GC导致掉帧 大量预分配拖慢启动 首帧渲染速度影响启动感知 四个指标互相影响 优化时需全局考虑

这张图告诉我们一个朴素的道理:CPU高了会拖累帧率和启动时间;内存泄漏了会导致频繁GC,进一步拉高CPU。做优化的时候,千万不要孤立地看一个指标。

我个人经验是:先解决内存问题,再从上往下调CPU,最后验证帧率和启动时间。这个顺序不一定放之四海皆准,但大多数场景下最高效。

一句话总结:CPU是发动机,内存是油箱,帧率是仪表盘,启动时间是点火的那一脚。四个都要看,但要看对地方。