struct dyld_chained_ptr_64_rebase
{
uint64_t target : 36, /*用于指针target*/
high8 : 8,
reserved : 7, // 0s
next : 12, /*用于提供下一个fixup偏移量(stride=4)*/
bind : 1; // Always 0 for a rebase
};
这种非常紧凑的编码意味着遍历链的整个过程就可以覆盖整个二进制文件。在作者的测试中,高出50%的dyld都可以大概被新的格式体系所优化并终极淘汰二进制包的大小,只有少量的元数据被生存下来以引导每个page的第一次fixup
重点顺序题目
明白fixup格式背后的动机,必须相识应用步调最昂贵的操纵之一:page fault。当应用步调启动过程中访问文件体系中的代码时,须要通过一个page fault将其从磁盘文件中带入内存。应用步调二进制文件中的每个16kb范围都被映射到内存中的一个页面。一旦页面被修改,只要应用步调不绝止,它就须要留在RAM中(dirty page)。iOS通过压缩近来没有利用的页面来优化dirty page.
应用步调启动时的fixup须要改变应用步调二进制中的地点,因此整个page都不可制止被标记为dirty。
当利用表结构存储fixup数据时,起首要办理rebase,然后是bind。这意味着rebase须要许多page fault,而且大部门是IO绑定[4]。另一方面,bind所访问的page是rebase所利用的page的30%。
在iOS15中,链式fixup将每个内存page的全部变革合并在一起。Dyld现在可以更快地处置惩罚它,只需调解一次内存,就可以同时完成rebase和bind。这使得像内存压缩器如许的操纵体系功能可以利用链式fixups中的信息,不须要在bind过程中归去解压旧page。这些变革,那么dyld中的rebase功能变成了一个无用的功能。
虽然这一变革只在以iOS15为目的是收效,但仍可以做许多变乱来优化应用步调的启动时间。
Reduce number of dynamic frameworks 淘汰动态框架数量
Reduce app size so less memory pages are used 淘汰应用步调的大小,以淘汰内存也的利用
Move code out of +load and static initializers 移出+load和静态初始化中的代码
Use fewer classes 利用更少的类
Defer work to after drawing the first frame 耽误工作到第一帧绘制之后