当前位置: 首页 > news >正文

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 看到一个 连续、干净且安全 的内存世界,也能让内核在背后高效地管理、隔离、复用有限的物理内存资源。

相关文章:

  • npm -v npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。来看看永久修改执行策略!
  • 【手机】vivo手机应用声音分离方案
  • 【Spring】深入解析 Spring AOP:切面优先级、切点表达式、自定义注解并实现、Spring AOP 的几种实现方式
  • Java 设计模式心法之第3篇 - 总纲:三大流派与导航地图
  • POSIX多线程,解锁高性能编程
  • 【iOS】Blocks学习
  • LangChain实现PDF中图表文本多模态数据向量化及RAG应用实战指南
  • 【身份证扫描件识别表格】如何识别大量身份证扫描件将内容导出保存到Excel表格,一次性处理多张身份证图片导出Excel表格,基于WPF和腾讯云的实现方案
  • Elasticsearch插件:IDEA中的Elasticsearch开发利器
  • LabVIEW 开发中数据滤波方式的选择
  • Ansys electronics安装多版本simulink打开s-function冲突解决方法
  • LlamaIndex 生成的本地索引文件和文件夹详解
  • [BJDCTF2020]EzPHP
  • 在麒麟KylinOS上通过命令行配置KYSEC的防火墙
  • android 多个viewmodel之间通信
  • Math.round(),Math.ceil(),Math.floor(),Math.sqrt(),Math.pow(),Math.abs()等!
  • Redis专题
  • 深度学习框架PyTorch——从入门到精通(3.3)YouTube系列——自动求导基础
  • 在Cursor编辑器上部署MCP(Minecraft Coder Pack)完整指南
  • PyTorch与TensorFlow模型全方位解析:保存、加载与结构可视化
  • 一季度全国纪检监察机关共处分18.5万人,其中省部级干部14人
  • 中国戏剧奖梅花奖终评启动在即,17场演出公益票将发售
  • 中汽协:杜绝虚假宣传与过度营销,确保用户清晰区别驾驶辅助与自动驾驶
  • 习近平向加蓬当选总统恩圭马致贺电
  • 医院招聘误发内部信息反获好评,求职者就需要这样的“敞亮”
  • 一图看懂|特朗普政府VS美国顶尖高校:这场风暴如何刮起?