iOS 中的虚拟内存 (理解为什么需要虚拟内存)

什么叫“虚拟地址空间”?

一句话:它是 CPU 看得见、App 以为自己独享,但实际上会被内核和硬件(MMU)动态翻译到真实 物理内存 的一整块“虚拟地图”。


1. 背景:为什么要“虚拟”?

需求虚拟地址空间能做什么
进程隔离给每个进程各分一套 0 → N 的地址,互不重叠,进程 A 读不到进程 B 的数据。
内存保护页级读/写/执行权限由页表标记;越界访问马上抛 EXC_BAD_ACCESS
弹性分配物理内存碎片化无关紧要,只要虚拟地址连续即可(“看上去一整块”)。
高级特性Copy‑on‑Write、内存映射文件 (mmap)、共享库复用、ASLR、PAC …

2. 在 iOS/arm64 上怎么实现?

2.1  MMU + 页表

  • MMU(Memory Management Unit):CPU 访存时,把 64‑bit 虚拟地址 拆成多级索引,通过页表(TTBR0 / TTBR1 指向)翻译成 48‑bit 物理地址
  • 页大小:iOS 全系 16 KiB;一页是虚拟空间管理的基本粒度。
  • 属性位:每个页表条目有 RWX 标志、用户/内核态位、内存类型(缓存/设备)等。

2.2 用户态 vs 内核态

区域arm64 虚拟高位典型范围 (48‑bit VA)说明
用户空间[0, 0x0000_FFFF_FFFF]0 → 128 TiB每个进程独占;App 代码、堆、栈、JIT、dyld shared cache…
内核空间[0xFFFF_0000_0000_0000, 2⁶⁴)顶部 128 TiB所有进程共享同一内核映像与数据;受 KTRR/PACDMA 保护
  • 两块空间由 异常级别(EL0 / EL1)TTBR 的切换隔离:App 只能使用下半部地址,高位一旦访问就触发权限异常。
  • 高位还用到 Top‑Byte‑Ignore (TBI):高 8 bit 可存自定义 tag(例如 Swift 的指针压缩、MTE 内存标记等)。

3. 64‑bit 设备典型虚拟地址布局(示意)

0x0000_0000_0000_0000
│  保留页 (NULL, guard)
├─ Mach-O 主可执行 (PIE, text+data)
├─ __DATA_CONST / 读取‑仅映射
├─ Heap   ⇡ 动态增长
│
│  (空洞,可供 mmap / JIT / stack 使用)
│
├─ Thread #N Stack ⇣ 向下增长
│    └─ Guard Page (不可访问)
│
├─ dyld shared cache   (私有或共享段)
└─  …  (高地址)
0x0000_FFFF_FFFF_FFFF   ← 用户空间顶
───────────────────────
0xFFFF_0000_0000_0000   ← 内核空间起
├─ Kernel Mach‑O + KEXT (KASLR)
└─ I/O 映射、vmalloc、kstack…
0xFFFF_FFFF_FFFF_FFFF   ← 64‑bit 顶

每次 App 启动设备冷启动 时,这些段会因为 ASLR 被整体“滑动”(加上 slide 值),但相对排列不变。


4. 与开发者相关的日常场景

你在做什么虚拟地址空间发生了什么
使用 malloc内核在“堆区”后方找一块尚未用过的虚拟页,映射物理内存并返回 虚拟指针
调试崩溃日志0x104a74000 这样的指针是“已经加了 slide 的虚拟地址”;需要减去 slide 才能对应符号表。
开启 JIT / Metal虚拟页被标记为可执行或设备内存,MMU 读到属性位后,用不同缓存策略访问。
访问空指针 / 越界目标虚拟页没有映射或权限位不匹配 → MMU 触发 Page Fault,内核抛异常。

5. 小结

  • 虚拟地址空间 = “给每个进程画的一张 私有地图”;
  • MMU + 页表 做“坐标翻译”与“边界安检”;
  • iOS 在这张地图上再叠加 ASLR、PAC、KTRR、代码签名 等多重防护。

借助虚拟地址空间,iOS 既能让每个 App 看到一个 连续、干净且安全 的内存世界,也能让内核在背后高效地管理、隔离、复用有限的物理内存资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依旧风轻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值