本文知識點提煉: 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