二进制重排(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,不会造成严重磁盘浪费。