App的启动时间可以按2个大块进行划分,【T1 main函数之前】和【T2 main函数到Root ViewController的出现】。这里介绍的是【T1 main函数之前】阶段的耗时怎么在Xcode里面查看。
0x0:修改Edit Scheme
0x1:修改DYLD_PRINT_STATISTICS
值为${DEBUG_ACTIVITY_MODE}
或者填1
也可以
0x2:就是这么简单已经配置完成了,接下来在Debug模式下启动项目就可以在控制器看到了一段特别的输出了:
越狱设备下控制台的输出:
Total pre-main time: 2.8 seconds (100.0%)
dylib loading time: 29.41 milliseconds (1.0%)
rebase/binding time: 154.91 milliseconds (5.3%)
ObjC setup time: 129.72 milliseconds (4.5%)
initializer time: 2.5 seconds (89.0%)
slowest intializers :
libSystem.B.dylib : 12.18 milliseconds (0.4%)
MobileSubstrate.dylib : 602.23 milliseconds (20.9%)
libglInterpose.dylib : 84.18 milliseconds (2.9%)
jzzk : 2.1 seconds (73.6%)
未越狱设备下控制台的输出:
Total pre-main time: 756.23 milliseconds (100.0%)
dylib loading time: 48.12 milliseconds (6.3%)
rebase/binding time: 80.09 milliseconds (10.5%)
ObjC setup time: 28.72 milliseconds (3.7%)
initializer time: 599.28 milliseconds (79.2%)
slowest intializers :
libSystem.B.dylib : 6.16 milliseconds (0.8%)
libglInterpose.dylib : 329.30 milliseconds (43.5%)
jzzk : 457.02 milliseconds (60.4%)
通过控制台很清楚可以看到各阶段的加载时间:
- 【Total pre-main time 】,既总耗时2.3s。
ps:如果大于20s会被系统watch dog杀掉。
- 【dylib loading】,加载可执行文件(App 的.o 文件的集合), App所需的所有动态链接库都在这个阶段加载
- 【rebase/binding time: 122.81 milliseconds (4.1%)】,对动态链接库进行 rebase 指针调整和 bind 符号绑定
- 【Objc setup】,OC runtime运行时的初始处理,包括 Objc 相关类的注册、category 注册、selector 唯一性检查等
- 【initializer】,包括了执行 +load() 方法、attribute((constructor)) 修饰的函数的调用、创建 C++ 静态全局变量
- 【slowest intializers】,会列出加载最慢的几个dylib文件,我这边列出了
libSystem.B.dylib
、libglInterpose.dylib
、MobileSubstrate.dylib
三个 - libSystem.B.dylib,一个系统的动态库。
- libglInterpose.dylib,一个系统的动态库。
- MobileSubstrate.dylib,如果是越狱的设备会加载这个大型动态库,tweak也是基于这个库来完成的。