启动优化

173 阅读2分钟

一、启动流程

dyld: 动态链接器,可以用来装载Mach-O文件(可执行文件、动态库等) APP的可执行文件,同时会递归加载所有依赖的动态库 当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行下一步的处理

dyld 怎么加载动态库

_dyld_start开始 第一步,先通过环境变量配置的值,获取当前运行的架构 第二步,检测是否开启了共享缓存,是否映射到了共享区域,比如UIKit,Foundation等 第三步,主程序的初始化,初始化一个imageLoader对象 第四步,递归遍历所有需要的动态库,动态的插入 第五步,链接主程序 第六步,链接插入的动态库 第七步,弱符号绑定,bind rebase 第八步,执行所有的初始化方法, 第九步,寻找main入口

runtime: 调用map_images进行可执行文件内容的解析和处理 在load_images中调用call_load_methods,调用所有Class和Category的+load方法 进行各种objc结构的初始化(注册Objc类 、初始化类对象等等) 调用C++静态初始化器和__attribute__((constructor))修饰的函数

到此为止,可执行文件和动态库中所有的符号(Class,Protocol,Selector,IMP,…)都已经按格式成功加载到内存中,被runtime 所管理

main: UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法

二、启动优化

启动优化:重启手机(优化前2.225,优化后1.932)和未重启手机(优化前1.531,优化后0.910)

dyld阶段:(优化100ms) 减少动态库、合并一些动态库(定期清理不必要的动态库) 减少Objc类、分类的数量、减少Selector数量(定期扫描一下项目里面的无用的类、分类,这里需要将方法找出来,然后推进大家负责的模块,去删除。合并功能类似的类和扩展) 通过减少IO操作量级优化 - 压缩资源图片 减少C++虚函数数量

runtime阶段:(优化20ms) 用+initialize方法和dispatch_once取代所有的__attribute__((constructor))、C++静态构造器、ObjC的+load

main阶段:(优化500ms) 在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在finishLaunching方法中 按需加载

在iOS编译的产物 Mach-o文件中 __DATA __objc_classrefs 段记录了引用类的地址,__DATA __objc_classlist段记录了所有类的地址,取差集可以得到未使用的类的地址,然后进行符号化,就可以得到未被引用的类信息。