使用虚拟内存的目的之一是解决物理内存资源紧张的问题。dyld在加载二进制时,会使用mmap将Mach-O文件映射到虚拟内存地址空间中,此时并不会占用过多的物理内存。当读取一个虚拟内存地址时,如果该地址在物理内存中并不存在,会触发一次缺页中断(Page Fault),这个时候才将文件内容读取至物理内存中。
由于虚拟内存的机制,应用启动时不会把所有数据加载到内存,而是以页为单位逐步从磁盘中加载,内存中的虚拟地址和磁盘中的物理地址有个映射关系。当程序执行时,如果发现要访问的东西不在内存里,就会触发一次page fault ,去磁盘中加载新的一页。
启动阶段有很多方法要调用,而这些方法在Mach-O中的位置又是在编译时确认的。如果有10个方法刚好在不同页,可能就要产生10次page fault 。
二进制重排要做的就是将启动阶段要用到的方法,在编译时提前确定,通过.order文件告诉编译器,这样这些方法会排布在Mach-O的最前面,之前的10次page fault 很可能就变成一两次page fault。
通过在Other C Flags中添加-fsanitize-coverage=func,trace-pc-guard 再通过
__sanitizer_cov_trace_pc_guard记录启动阶段所有方法的调用,再将这些写入到.order文件中,在Xcode的ORDER_FILE 设置中配置即可生效。
2181

被折叠的 条评论
为什么被折叠?



