启动优化的再次探索

阶段一

启动优化的指标是尽量缩短应用启动的时间(用户等待时间减少,增加体验)。业界这方面做的比较出色的如支付宝等,基本达到“秒起”。
关于启动优化的文章网上有很多了,这边只是简单的提下,不做详细阐述。

启动优化一般指的是冷启动,其中分为三个阶段:

  • main()之前
  • main()
  • main()之后

其中main()之前阶段以dyld主导,涉及到耗时的部分主要有

  1. 加载动态库
  2. rebase
  3. binding
  4. load
  5. ...

有兴趣的可以参考我之前写的一篇文章谈谈dyld ,更为详细的内容可以参考WWDC2013 Session

阶段二

对于一般的app,做完阶段一之后,其实差不多了,也没必要再次优化。但是对于一些超级app来说指标越来越高,那么还有哪些优化措施可以再次缩短启动时间呢?

二进制文件重排

二进制文件重排本质是减少缺页中断次数,从而减少部分启动时间。缺页中断指的是当进程访问一个虚拟内存Page而对应的物理内存却不存在时,触发内核分配物理内存,有需要的话会从磁盘mmap读入数据的行为。



通过App Store渠道分发的App,Page Fault还会进行签名验证,所以一次Page Fault的耗时比想象的要多:

默认布局

编译器在生成二进制文件的时候,默认按照链接.o文件顺序写文件,以目标文件内部的函数顺序写函数。

启动优化的再次探索_第1张图片
默认

简化问题: 假设我们只有两个page: page1/page2,其中绿色的method1和method3启动时候需要调用,为了执行对应的代码,系统必须进行两个Page Fault。

但如果我们把method1和method3排布到一起,那么只需要一个Page Fault即可,这就是二进制文件重排的核心原理 。

启动优化的再次探索_第2张图片
重排

其中二进制文件重排关键是得到order file

Alters the order in which functions and data are laid out. For each section in the output file, any symbol in that section that are specified in the order file file is moved to the start of its section and laid out in the same order as in the order file file.

App 二进制文件重排已经被玩坏了已经讲解的很详细了,原理:基于clang内置的代码覆盖工具,做到全局的AOP,在 SanitizerCoverage 的回调函数里将地址先收集到队列里,调用 AppOrderFiles()后会停止收集,并将队列中的 PC 地址依次翻译符号,最后去重
这样就得到了order file. 在xcode build settings中设置order file选项之后,重新build生成的应用较上次未优化前减少了15%左右.

阶段三

一开始没想到还有这种骚套路,直到我今天看到了支付宝分享的一篇文章支付宝客户端架构解析:iOS 客户端启动性能优化初探。通过使用Background Fetch来做到"热启动"。Background Fetch本来是做后台数据刷新用的。它其实类似于一种轮询机制,系统会学习并且适应用户的习惯,在用户使用之前,后台进行调度来启动应用,更新数据。不过也有其弊端,比如进程唤醒的次数远大于使用的次数等

你可能感兴趣的:(启动优化的再次探索)