mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 20:00:40 +00:00
99 lines
3.9 KiB
Markdown
99 lines
3.9 KiB
Markdown
# 二进制重排
|
||
|
||
|
||
## 启动检测
|
||
|
||
- 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 time:Swift 这部分占优势
|
||
|
||
initializer time:load 方法耗时。
|
||
|
||
slowest intializers:
|
||
|
||
libS
|
||
|
||
libMain
|
||
|
||
|
||
|
||
查看 LinkMap。发现方法展示顺序是按照,写代码的顺序展示的。
|
||
|
||

|
||
|
||
|
||
|
||
## 有没有办法将 App 启动需要的方法集中收拢?
|
||
|
||
1. 在 Xcode 的 Build Settings 中设置 **Order File**,Write 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 插桩可行
|
||
|
||
|
||
|
||
|
||
|
||
- https://mp.weixin.qq.com/s/SUHaGD1T2Vce4Ag-qgxtgg |