Files
knowledge-kit/Chapter1 - iOS/1.91.md
杭城小刘 e89fe0ca1c docs: 内容
2020-11-08 15:51:47 +08:00

4.1 KiB
Raw Blame History

二进制重排

  1. 清吟街社保

  2. 社保清单、户口本、身份证带上去做工作信息变更。信息变更为街道

  3. 月底入住

身份证、社保清单、失业证明,去办理

启动检测

  • App 动态库不要超过6个。

  • 静态库:影响 Mach-O 文件。

  • 动态库:影响 App 启动时间。

虚拟内存、物理内存、内存分页

早期计算机内部都是物理内存。物理内存一个问题就是安全问题,通过地址访问到别的应用程序的数据。进程如果能直接访问物理内存无疑是很不安全的,(诞生了解决方案:虚拟内存)所以操作系统在物理内存的上又建立了一层虚拟内存。

一个应用程序在使用的时候并不是全部使用的,往往是使用了一个应用程序的某个或者某几个功能。

所以早期工程师的第一个解决方案是将一个应用程序分块,按需加载功能模块的内存地址数据。

虚拟内存是间接访问了内存条。

内存分页iOS 一页就是16KB。

物理内存如果满了,则将最活跃的内存数据,覆盖掉,最不活跃的内存数据;

ASLR为了安全问题诞生。

自己的代码中有 NSLog 代码,可是 NSLog 函数的代码实现在 Foundation 动态库中。

App 启动则用 dyld 去加载库,共享缓存库。

虚拟地址:偏移是编译后就能确定的。

内存缺页异常:在使用中,访问虚拟内存的一个 page 而对应的物理内存缺不存在(没有被加载到物理内存中),则发生缺页异常。影响耗时,在几毫秒之内。

什么时候发生大量的缺页异常?一个应用程序刚启动的时候。

启动时所需要的代码分布在第一页、第二页、第三页...第200页。这样的情况下启动时间会影响较大所以解决思路就是将应用程序启动刻所需要的代码二进制优化一下统一放到某几页这样就可以避免内存缺页异常则优化了 App 启动时间。

dylib loading time

rebase/binding time 修正符号是由于 ASLR 导致。binding time 是动态库去 bind lazy table、non-lazy table 所占用的时间。rebase 地址偏移ASLR。 rebase 的时间如何缩小Mach-O 文件大小变小。 binding time 变小则需要动态库变小。2者优化手段冲突

Objc setup timeSwift 这部分占优势

initializer timeload 方法耗时。

slowest intializers

libS

libMain

查看 LinkMap。发现方法展示顺序是按照写代码的顺序展示的。

![image-20200814211215976](/Users/lbp/Library/Application Support/typora-user-images/image-20200814211215976.png)

有没有办法将 App 启动需要的方法集中收拢?

  1. 在 Xcode 的 Build Settings 中设置 Order FileWrite Link Map Files 设置为 YES进行观察

  2. 如果你给 Xcode 工程根目录下指定一个 order 文件,比如 refine.order,则 Xcode 会按照指定的文件顺序进行二进制数据重排。分析 App 启动阶段,将优先需要加载的函数、方法,集中合并,利用 Order File减小缺页异常从而减小启动时间。

如何拿到启动时刻所调用的所有方法名称

clang 插桩,才可以 hook OC、C、block、Swift 全部。LLVM 官方文档。

二进制重排提升 App 启动速度是通过「解决内存缺页异常」(内存缺页会有几毫秒的耗时)来提速的。

一个 App 发生大量「内存缺页」的时机就是 App 刚启动的时候。所以优化手段就是「将影响 App 启动的方法集中处理放到某一页或者某几页」虚拟内存中的页。Xcode 工程允许开发者指定 「Order File」可以「按照文件中的方法顺序去加载」可以查看 linkMap 文件(需要在 Xcode 中的 「Buiild Settings」中设置 Order File、Write Link Map Files 参数)。

其实难点是如何拿到启动时刻所调用的所用方法?代码可能是 Swift、block、c、OC所以hook 肯定不行、fishhook 也不行,用 clang 插桩可行