IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【面试】【iOS】为什么说减少分类的数量能够减少启动过程的耗时 -> 正文阅读

[移动开发]【面试】【iOS】为什么说减少分类的数量能够减少启动过程的耗时

需要理解的核心问题:

指针到底指的是什么?


Mach-o 中有很多符号,指向当前的mach-o的,也有指向其他的dylib的,比如prinf。那么在运行时,代码如何准确的找到printf的地址呢?
Mach-o中 采用了PIC技术,全称 Position Independ code。当你的程序要调用printf的时候,会先在__DATA段中建立一个指针,指向printf,在通过这个指针实现间接调用。dyld这时候需要做一些fix-up工作,即帮助应用程序找到这些符号的实际地址,主要包括两部分:

Rebase:修正内部(指向当前mach-o文件)的指针指向
Bind 修正外部指针指向

Rebasing

在过去,会把 dylib 加载到指定地址,所有指针和数据对于代码来说都是对的,dyld?就无需做任何 fix-up 了。如今用了 ASLR 后会将 dylib 加载到新的随机地址(actual_address),这个随机的地址跟代码和数据指向的旧地址(preferred_address)会有偏差,dyld?需要修正这个偏差(slide),做法就是将 dylib 内部的指针地址都加上这个偏移量,偏移量的计算方法如下:

Slide = actual_address - preferred_address

然后就是重复不断地对?__DATA?段中需要 rebase 的指针加上这个偏移量。这就又涉及到 page fault 和 COW。这可能会产生 I/O 瓶颈,但因为 rebase 的顺序是按地址排列的,所以从内核的角度来看这是个有次序的任务,它会预先读入数据,减少 I/O 消耗。

之所以需要Rebase,是因为刚刚提到的?ASLR?使得地址随机化,导致起始地址不固定,另外由于?Code Sign,导致不能直接修改?ImageRebase的时候只需要增加对应的偏移量即可。(待Rebase的数据都存放在**__LINKEDIT**中,可以通过MachOView查看:Dynamic Loader Info -> Rebase Info)

__LINKEDIT?段它的作用是包含如何加载整个文件的「元数据」。例如符号表,字符串表和重定位表。代码签名后每页的加密散列值也会存储到这里。

Binding

Binding 是处理那些指向 dylib 外部的指针,它们实际上被符号(symbol)名称绑定,也就是个字符串。之前提到?__LINKEDIT?段中也存储了需要 bind 的指针,以及指针需要指向的符号。dyld?需要找到 symbol 对应的实现,这需要很多计算,去符号表里查找。找到后会将内容存储到?__DATA?段中的那个指针中。Binding 看起来计算量比 Rebasing 更大,但其实需要的 I/O 操作很少,因为之前 Rebasing 已经替 Binding 做过了。


Binding就是将这个二进制调用的外部符号进行绑定的过程。 比如我们objc代码中需要使用到NSObject, 即符号_OBJC_CLASS_$_NSObject,但是这个符号又不在我们的二进制中,在系统库 Foundation.framework中,因此就需要Binding这个操作将对应关系绑定到一起。

Objective-C 中有很多数据结构都是靠 Rebasing 和 Binding 来修正(fix-up)的,比如?Class?中指向超类的指针和指向方法的指针。
?

Rebase和Bind都是为了解决指针引用的问题。对于Objective C开发来说,主要的时间消耗在Class/Method的符号加载上,所以常见的优化方案是:
1、减少__DATA段中的指针数量。
2、合并Category和功能类似的类。比如:UIView+Frame,UIView+AutoLayout…合并为一个
3、删除无用的方法和类。

参考:

https://www.cnblogs.com/jukaiit/p/8110401.html

https://www.jianshu.com/p/b2a2af5665ef

https://www.cnblogs.com/cleven/p/12796608.html

参考的另一个原文:

启动过程:

一、加载dyld到App进程

什么是dyld?
dyld的全称是dynamic loader,它的作用是加载一个进程所需要的image。这里提到的image并不是我们认知的意思,指的是Executable,Dylib或者Bundle的一种。

此时内核对dyld都做了哪些事?
首先内核将App的执行文件加载到随机地址空间,之后内核将dyld的执行文件加载到随机地址空间,最后内核去执行执行dyld文件。

二、加载动态链接库

dyld拿到App的执行文件——mach-o文件后,首先从文件的header中解析出App依赖的dylib列表,找到每一个依赖的dylib。之后打开并读取dylib文件的起始位置,验证签名,确保dylib没有被篡改。验证签名后,对dylib中的每个segment调用mmap()。加载完一个dylib后,接着检查这个dylib所依赖的dylib,就这样的递归加载,直到所有的dylib加载完毕。通常一个App所依赖的动态库在100-400个左右,其中大多数都是系统的动态库,它们会被缓存到dyld shared cache,这样读取的效率会很高。

三、Rebase && Bind

首先先讲解一个概念——ASLR

ASLR:全称是Address space layout randomization,翻译过来就是“地址空间布局随机化”。

App被启动的时候,程序会被影射到逻辑的地址空间,这个逻辑的地址空间有一个起始地址,而ASLR技术使得这个起始地址是随机的。如果是固定的,那么黑客很容易就可以由起始地址+偏移量找到函数的地址。

为什么需要Rebase 和 Bind?

是因为刚刚提到的ASLR使得地址随机化,导致起始地址不固定,App和每个dylib加载到的都是随机地址空间,代码中原来的函数地址跟真实的函数地址会有差异。修复这个差异的过程就是rebasing和binding。

Rebase:Rebasing过程就是从__LINKEDIT取出函数指针,根据偏移量修改函数指针,存入__DATA中,Rebase解决了内部的符号引用问题。


 
Binding:当引用动态库其他的函数或者变量时,当前mach-o文件会指向其他dylib。这时候就需要Binding操作,dyld会根据符号表去找到相应函数和变量地址,Binding解决了修正外部指针指向的问题。

三、Objc Setup

Objective C是动态语言,为了维持它的动态性,在启动时,所以在执行main函数之前,需要把类的信息注册到一个全局的Table中。同时,Objective C支持Category,基于runtime的特性,在初始化的时候,也会把Category中的方法插入类结构体的方法列表中。

四、Initializers

完成objc的相关工作之后,需要完成动态库一些初始化工作:包括了执行 +load() 方法、attribute((constructor)) 修饰的函数的调用、创建 C++ 静态全局变量。运行“自下而上”,这样每个初始化器都可以调用它下面的dylibs,最后,Dyld在可执行文件中调用main()。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:51:06  更:2022-05-09 12:53:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:51:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码