早期计算机系统的内存地址都是物理地址。
应用程序会被完整加载到内存中,大量浪费空间。
可以直接访问内存地址实现跨进程,访问其他应用程序的进程。
物理内存中的数据不会清除,只覆写:这个过程是系统控制的,新的需要存进物理内存的数据,会被写入最不活跃的区域中。应用在后台可能被kill掉的原因之一就是被覆写了。
应用程序进程内拿到的地址并不是真实的地址,会通过虚拟页表映射到物理内存。
虚拟页表
iOS 一页数据 16kbMac 4K ,可以在终端中使用 PAGESIZE,命令获取
iOS 一页数据 16kb
iOS
16kb
Mac 4K ,可以在终端中使用 PAGESIZE,命令获取
Mac
4K
PAGESIZE
应用程序不会完整的加载,当用到某一页数据的时候,才会被加载到物理内存中。
流程:
系统和CPU配合进行地址翻译
硬件中MMU(内存管理单元)进行地址翻译
非常快
高速缓存
映射过的会被缓存不会重复翻译
找到物理地址
将数据加载进物理内存或读取
ASLR 每次启动为 虚拟页表 添加随机的偏移值,已获得更高的安全性。
ASLR
由于 虚拟页表 的存在,在我们代码访问的数据 page 没有被加载进内存的时候,就会出现 PageFault 缺页中断。而大量的缺页中断会影响应用的启动速度。
page
PageFault
缺页中断
而我们可以通过 二进制重排 对数据在 MachO 中的分页布局进行优化,使启动时相关的数据尽量在连续的 page 中,来减少 Page Fault 的次数。
二进制重排
MachO
Page Fault
这里我有进行一次相关的实战:二进制重排实践
Last updated 4 years ago