iOS 性能优化之二进制重排

0 阅读2分钟

二进制重排(order_file)在 dyld2 / dyld4 的效果差异

二进制重排的核心原理是:通过 order_file 在编译期调整 __TEXT,__text 段函数的磁盘物理排布,把冷启动最先执行的函数收拢到连续内存页中,减少启动阶段的 PageFault 缺页中断,减少磁盘 IO 耗时,从而优化冷启动速度。

1. dyld2 时代(iOS15 之前)—— 二进制重排效果极强

dyld2 采用全量串行加载机制:启动时一次性加载、解析、修复所有镜像,启动过程会产生大量 PageFault 缺页中断。

因此二进制重排收益非常明显,项目普遍可以提升 15%–20% 冷启动速度,是 dyld2 时代最核心、性价比最高的启动优化手段之一。

2. dyld4 时代(iOS15+)—— 二进制重排大幅降级

iOS15 之后系统全面升级为 dyld4,系统底层机制大幅重构,直接导致传统二进制重排收益断崖式下跌:

① dyld4 引入 PrebuiltLoader 预构建闭包缓存

第二次冷启动不再完整解析 Mach-O,直接读取预生成的闭包元数据,dyld 阶段几乎不再访问 __TEXT 代码段,pre‑main 阶段的 PageFault 被系统直接抹平大部分。

② dyld4 支持按需加载、Page-In Linking 延迟修复

不再一次性加载、修复所有类和符号,采用按需加载、延迟修符号的策略,dyld4 本身启动缺页极少。

③ 重排收益场景被大幅压缩

dyld4 下 order_file依然生效,Mach-O 符号顺序确实会被重排,语法完全兼容,不会失效。

但整体优化收益从原来的 20% 左右,下降到仅 3%–5%,几乎没有业务优势,属于锦上添花,不再是核心优化手段。

3. dyld2 与 dyld4 核心区别总结

  • dyld2:全量加载、全量解析、一次性修复符号,大量 PageFault,二进制重排收益巨大(≈20%)。
  • dyld4:按需加载、闭包缓存、延迟修复符号,系统自带大量优化,缺页极少,二进制重排收益极低(≈4%)。

4. dyld4 时代真正有效的启动优化(替代二进制重排)

dyld4 下 PageFault 已经不是瓶颈,真正拖慢 pre‑main 的是:

  • 大量动态库加载开销
  • 多余 +load / C++ 全局构造函数阻塞 pre‑main
  • 大量分类、类数量导致 Building Closure 阶段耗时

所以 dyld4 时代:删 load、减动态库、懒初始化,远比二进制重排重要。

PrebuiltLoader 闭包缓存,每个 App 生成一份独立缓存文件,单份通常几十 KB~ 几百 KB,大 App 最高 1‑2MB,不会造成严重磁盘浪费。