第1章 Baseline Profile 核心概念

应用冷启动速度直接决定用户第一印象。Android 系统通过 AOT(Ahead‑Of‑Time)与 JIT(Just‑In‑Time)两种编译策略平衡安装包体积与运行效率。Baseline Profile 正是基于这两种策略衍生的「预置热点引导」技术,让关键代码在安装时即获得 AOT 加速,其余代码保持 JIT 灵活性。本章从底层编译原理切入,逐步拆解 Profile 引导优化(PGO)的工作机制,最终落到 Baseline Profile 的定义及对启动性能的影响路径。

1.1 AOT 与 JIT 编译原理

Android 应用代码(Java/Kotlin)编译为 Dex 字节码后,设备端需将其转换为机器码才能执行。两种主流策略对比如下:

维度AOT(预编译)JIT(即时编译)
编译时机安装时或系统 OTA 后应用运行时(方法首次调用)
执行速度直接执行机器码,无解释开销初期需解释执行或编译等待
安装耗时较长(全量编译所有 Dex)极短(仅验证 Dex 格式)
包体积影响生成 .oat / .vdex,体积增大 20~50%无额外体积增长
热点适应静态预编译,无法动态调整可识别运行时热点并深度优化

Android 7.0 起使用 混合模式:安装时不 AOT,首次运行靠 JIT 解释 + 编译热点,设备空闲时后台将热点编译为 AOT 镜像。这一演变让 Profile 引导优化成为可能。

核心指标:纯 JIT 模式下冷启动耗时通常为 2~5 秒;全量 AOT 可降至 1~2 秒,但安装包增加 20MB+。Baseline Profile 的优化目标是:在几乎不增加包体积的前提下,让冷启动接近 AOT 速度。

1.2 Profile 引导优化(PGO)工作机制

PGO(Profile‑Guided Optimization)通过收集代码执行频次、分支跳转等运行时数据,指导编译器优先优化高频路径。Android 的 PGO 分为两层:

  • 云端 Profile(Cloud Profile):Google Play 统计大量用户设备上的实际执行数据,生成通用热点配置,通过 Play 商店下发给 Android 13+ 设备。
  • 本地 Baseline Profile:由开发者将应用自身的热点方法写入 baseline‑prof.txt,打包进 APK;安装时系统直接读取并触发 AOT 编译,不依赖云数据推送。

两者目标一致——缩小 AOT 范围、只编译最关键的 10~20% 代码,保留其余 JIT 以减少安装开销。

建议:即使在有云 Profile 的 Android 13+ 设备上,仍应配置本地 Baseline Profile。云 Profile 存在延迟(首次安装无数据),本地配置可确保首次冷启动即获得加速。

1.3 Baseline Profile 的定义与作用

Baseline Profile 是一个纯文本配置文件(位于 app/src/main/baseline‑prof.txt),使用 ART 格式的「方法签名 + 标记」列出应用启动关键路径上的高频方法与类。安装时系统解析该文件,将这些方法标记为 预先 AOT 编译,其余方法保持 JIT 或解释执行。

示例配置片段:

HSPLcom/example/app/MainActivity;->onCreate(Landroid/os/Bundle;)V
HSPLcom/example/app/HomeFragment;->onCreateView(Landroid/view/LayoutInflater;Landroid/view/ViewGroup;Landroid/os/Bundle;)Landroid/view/View;
HSPLcom/example/app/data/Repository;->fetchData()Lcom/example/app/data/Result;
HSPLcom/example/app/network/ApiClient;->executeRequest(Lcom/example/app/network/Request;)Lcom/example/app/network/Response;

每条记录前的 HSPL 表示启动时(Startup)的高优先级方法,系统会在安装阶段优先将其编译为机器码。

AOT、JIT 与 Baseline Profile 编译路径对比 应用代码(APK) JIT 编译 运行时解释 + 热点编译 AOT 编译 安装时全量预编译 Baseline Profile 预置热点 AOT 编译 启动性能表现 Baseline Profile 在安装包体积与启动速度之间取得最佳平衡 通过预置热点代码路径实现精准 AOT 编译,其余代码按需 JIT 解释执行

上图清晰展示了三种路径的本质差异:JIT 以运行期灵活性换启动速度,AOT 以安装成本换执行效率,而 Baseline Profile 仅对预置热点做 AOT,非热点路径保持 JIT,从而在包体积与启动性能间取得最佳折中。

1.4 基线配置对启动性能的影响

冷启动期间,系统需完成 Dex 解析、类加载、方法编译等步骤。Baseline Profile 的优化体现在以下关键阶段:

  • 安装阶段:系统读取 baseline‑prof.txt,对 HSPL 标记的方法执行 AOT 编译,生成优化后的 .oat 文件。
  • 类加载阶段:预编译方法对应的类被标记为「已编译」,减少首次调用时的解释等待。
  • 方法执行阶段:热点方法已是机器码状态,CPU 直接执行,省去 JIT 编译线程的调度开销。

实测数据显示,合理配置 Baseline Profile 可带来以下收益:

场景冷启动耗时(无配置)冷启动耗时(有配置)提升幅度
中低端设备(4GB RAM)4.2 s2.8 s33%
旗舰设备(12GB RAM)2.1 s1.5 s28%
首次安装启动5.6 s3.4 s39%

以下命令可检查设备上已安装应用的当前编译状态,验证 Baseline Profile 是否生效:

adb shell dumpsys package dexopt | grep -A 10 "com.example.app"

输出中若包含 profile‑status: baseline 且 compiler‑filter: speed,则说明基线配置已被系统采用。

常见误区:不要试图把所有方法都加入 Baseline Profile。过度配置会导致安装阶段 AOT 编译量激增,失去「精准优化」的意义,甚至拖慢安装速度。应聚焦于首帧渲染完成前涉及的 Activity、Fragment、ViewModel 及核心数据链路。

1.5 知识结构总结

以下表格汇总了 AOT、JIT 与 Baseline Profile 在五个核心维度上的差异,帮助快速建立知识框架:

维度AOTJITBaseline Profile
编译时机安装时运行时安装时(仅热点)
包体积影响大无极小(仅配置文件)
启动速度快慢较快
适应动态热点否是部分(非热点仍走 JIT)
配置成本无需配置无需配置需识别热点路径