> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/ni-xiang/17.-xu-ni-nei-cun.md).

# 17.虚拟内存

### 一、物理内存

早期计算机系统的内存地址都是物理地址。

#### 1.1 内存不够用

应用程序会被完整加载到内存中，大量浪费空间。

![虚拟内存-应用程序完整加载](/files/kN9kjSSuXfuMmFKyskXH)

#### 1.2 物理地址不安全

可以直接访问内存地址实现跨进程，访问其他应用程序的进程。

![虚拟内存-直接访问物理地址](/files/zl5QdwNoNOUIeZsdUNy4)

***物理内存中的数据不会清除，只覆写***：这个过程是系统控制的，新的需要存进物理内存的数据，会被写入最不活跃的区域中。应用在后台可能被kill掉的原因之一就是被覆写了。

### 二、虚拟内存

#### 2.1 虚拟页表

应用程序进程内拿到的地址并不是真实的地址，会通过`虚拟页表`映射到物理内存。

> `iOS` 一页数据 `16kb`
>
> `Mac` `4K` ，可以在终端中使用 `PAGESIZE`，命令获取

#### 2.2 内存优化

应用程序不会完整的加载，当用到某一页数据的时候，才会被加载到物理内存中。

![虚拟内存](/files/TqKwLeJYvdogFUsHmhwI)

流程：

* 系统和CPU配合进行地址翻译
  * 硬件中MMU（内存管理单元）进行地址翻译
    * 非常快
    * 高速缓存
      * 映射过的会被缓存不会重复翻译
  * 找到物理地址
* 将数据加载进物理内存或读取

#### 2.3 ASLR

`ASLR` 每次启动为 `虚拟页表` 添加随机的偏移值，已获得更高的安全性。

### 三、 缺页中断

由于 `虚拟页表` 的存在，在我们代码访问的数据 `page` 没有被加载进内存的时候，就会出现 `PageFault` `缺页中断`。而大量的缺页中断会影响应用的启动速度。

而我们可以通过 `二进制重排` 对数据在 `MachO` 中的分页布局进行优化，使启动时相关的数据尽量在连续的 `page` 中，来减少 `Page Fault` 的次数。

> 这里我有进行一次相关的实战：[二进制重排实践](/wiki/ios/you-hua/03.-er-jin-zhi-zhong-pai-shi-jian.md)
