iOS内存相关知识还有二进制重排的介绍
二进制重排
- 大型项目用的比较多
- iOS内存
-
物理内存:没有办法直接访问物理内存,即内存条的真实地址
-
虚拟内存:LLDB调试如打印内存地址或者真实的内存地址,都是虚拟内存
-
早期的内存都是物理内存,内存不够时,给出内存不够的弹窗
缺点: (所以引入虚拟内存)
- 软件一次性加载到内存中,对内存消耗太大
- 外挂,检索内存,修改数据,如修改金币数量,跨进程访问数据
- 每一个进程,都有对应的映射表,映射到物理内存
- 访问虚拟内存
- 虚拟内存映射到物理内存
- 访问数据,映射,然后cpu,通过硬件MMU,和操作系统去从虚拟内存到物理内存.
- 一个进程对应于一个虚拟页表
- 一个虚拟页表有好多段
- 进程并不是整个的被载入到内存,只有用户数据正在活跃的数据载入。
- 分段载入时,段的大小,涉及到分页,有哪些页正在活跃,就载入到内存
- 不可以字节为单位,否则映射表就会比较大,应以页为单位
- 页的地址+偏移地址,找到某一个数据
- 页的大小,MacOS,Linux,页是4K的大小,iOS一页是16K.
- 环境变量PAGESIZE,可以看出页的多少,通过终端.
- 以上也是虚拟内存产生的原因
-
用户点开一个app,是一页一页加载
-
进程访问数据的时候,访问的是虚拟页表,如果这个数据通过页表查询,不在物理内存上,那么产生阻塞,阻塞当前进程,叫缺页异常。
-
由操作系统触发。
-
然后到磁盘上查找这一页,加载到物理内存,加载完毕,进程继续。访问进程数据,cpu通过mmu进行地址翻译,得知这一页数据已经加载,有映射关系,通过虚拟内存找到物理内存真实数据,再加载。
-
虚拟内存势必消耗时间,毫秒级别
-
但是速度会很快,用户基本感知不到缺页异常,可以几乎忽略不计
-
概念:页面置换
-
用户点开某一页,加载到物理内存时,如果物理内存满了,将物理内存中不活跃的页,进行替换.
问题:什么样的时刻,缺页异常会同时大量的出现?
app启动的时候:数据加载、方法调用,一定会出现耗时
-
技术层面
降低缺页异常次数 -> 启动优化 -
优化方案?
-
合并动态库是一个动态库加载时间减少的方案
-
不加载不必要的页
-
Xcode工程的build settings中有一个设置项:Write Link Map file
-
编译工程得到product后,可以show in finder去找到LinkMap-normal-arm64.txt文件
-
文件里面有Symbols的执行顺序,这个顺序跟compile source files的添加顺序有关。
-
而单个文件中的方法执行顺序,跟代码书写顺序相同。
-
假设:
-
如果启动时,有500个缺页异常,因为启动时刻需要调用的方法分别分布在了这500页数据里面。
-
但是这500页里的数据里,不全都是启动时需要调用的方法.
-
如果,让app链接的顺序,按照启动调用顺序来进行排列,那么启动时必要的方法都会优先执行
暂无评论,快来发表第一条评论吧