本文知识点提炼: 1、APP 启动时 PageFault 的性能分析 2、静态库插桩重排方案的技术原理
背景
▐ APP 启动 和 PageFault
重排方案
▐ 如何获取方法的执行顺序
为了生成 order_file , 我们需要确定应用启动时方法的执行顺序。之前抖音和 facebook 都分享过自己的方案,在实际操作的过程中,我们发现抖音和 facebook 的方案并不适用于手淘。
▐ 静态库插桩
-[MyApp window]: 0000000000002d88 adrp x8, #0x 0000000000002d8c ldrsw x8, [x8, #0xf18] ; 0x2f18@PAGEOFF, _OBJC_IVAR_$_MyApp._window 0000000000002d90 ldr x0, [x0, x8] 0000000000002d94 ret
-[MyApp window]: 0000000000002ebc stp x29, x30, [sp, #-0x10]! 0000000000002ec0 mov x29, sp 0000000000002ec4 bl _record_method 0000000000002ec8 ldp x29, x30, [sp], #0x 0000000000002ecc adrp x8, #0x 0000000000002ed0 ldrsw x8, [x8, #0xc0] 0000000000002ed4 ldr x0, [x0, x8] 0000000000002ed8 ret
▐ 生成 order file
address = pc - slide. // 因为ASLR, APP 可执行文件随机载入的原因,需要处理一下偏移 量。
# Symbols: # Address Size File Name 0x100001630 0x00000039 [ 2] -[ViewController viewDidLoad] 0x100001670 0x00000092 [ 3] _main 0x100001710 0x00000080 [ 4] -[AppDelegate application:didFinishLaunchingWithOptions:] 0x100001790 0x00000040 [ 4] -[AppDelegate applicationWillResignActive:] 0x1000017D0 0x00000040 [ 4] -[AppDelegate applicationDidEnterBackground:] 0x100001810 0x00000040 [ 4] -[AppDelegate applicationWillEnterForeground:] 0x100001850 0x00000040 [ 4] -[AppDelegate applicationDidBecomeActive:] 0x100001890 0x00000040 [ 4] -[AppDelegate applicationWillTerminate:]
▐ 更改符号的排列顺序
//Order file 内容例子: +[xxxxx1 load] +[xxxxx2 swizzleResumeAndSuspendMethodForClass:] +[xxxxx3 load] +[xxxxx4 initialize]___ +[xxxxx5 initialize]_block_invoke +[xxxxx6 initialize]___ +[xxxxx7 initialize]_block_invoke ...
优化效果
通过精准的启动函数重排,最后重排效果还是很可观的,在 iPhone6 上优化了400ms 的启动时间。
参考
抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15% Improving iOS Startup Performance with Binary Layout Optimizations https://atscaleconference.com/videos/performance-scale-improving-ios-startup-performance-with-binary- layout-optimizations/ Linux下Page Fault的处理流程 https://cloud.tencent.com/developer/article/1459526