iOS 为什么没有内存交换分区(swap)

14 阅读4分钟

先直接回答:iOS 确实没有传统意义上的 swap 分区。有 swap 的典型代表是桌面 Linux、macOS、Windows,以及 Android(严格说是 zram 压缩交换,但机制上属于交换的一种)。

下面把“swap 分区是什么、谁有、iOS 为什么没有、没有的话靠什么”讲清楚。

1. swap 分区是什么?

swap(交换空间) 是操作系统在磁盘/闪存上划出的一块区域,用来存放内存里暂时不用的页(page)。

工作逻辑:

  1. 物理内存(RAM)不够用了。
  2. 内核挑选一些“最近不常用”的内存页。
  3. 把这些页写到磁盘上的 swap 区,然后在 RAM 里腾出空间。
  4. 以后某个进程再访问这些页时,触发缺页异常(page fault),内核再把它们从 swap 读回内存。

本质:用磁盘空间换内存空间,代价是访问变慢(磁盘比 RAM 慢几个数量级)。

Linux 上 free -h 看到的 Swap: 那一行,就是这个。

2. 谁有 swap?

系统有没有 swap形式
桌面 Linux有独立 swap 分区,或 swap 文件
macOS有swap 文件(/private/var/vm/swapfile*),动态增长
Windows有pagefile.sys(页面文件)
Android有主要用 zram(内存里压缩,不落盘),部分设备还有 swap 文件
iOS没有—

3. iOS 为什么没有 swap?

几个关键原因:

① 闪存寿命和性能

iPhone 用的是 NAND 闪存。如果频繁把内存页换进换出,会带来大量写入,既伤闪存寿命,又拖慢速度。移动设备对功耗和延迟极其敏感,swap 的随机读写会显著拉高功耗、拖慢响应。

② 移动端的使用模型不同

桌面可以同时开几十个应用长期驻留,需要 swap 来“假装内存很大”。而 iOS 的应用模型是:前台应用优先,后台应用随时可以被杀。系统不打算让所有 App 都常驻内存,所以它选择了更“暴力”但更干脆的策略——直接杀进程,而不是费劲把内存换到磁盘。

③ 苹果的取舍:宁可杀,不换

换出到磁盘意味着用户切回那个 App 时会有明显的卡顿(要把页读回来)。iOS 的设计哲学是:让用户切回时 App 重新启动,体验反而更可预期。这就是 Jetsam 存在的背景。

4. 没有 swap,iOS 靠什么?

主要靠三样东西:

① Jetsam(内存紧张时杀进程)

内核监控内存压力,按优先级杀进程。优先级大致考虑:

  • 前台 App 优先级最高,最后被杀。
  • 后台 App、系统守护进程按重要性和占用内存排序。
  • 被杀时通常给 SIGKILL(走之前讨论过的内核直接终止路径)。

你崩溃日志里看到的 0x8badf00d 是 watchdog,而 Jetsam 杀进程对应的是 EXC_CRASH (SIGKILL) / JetsamEvent 这类记录,和 watchdog 是两回事。

② 内存压缩(Compressor)

iOS/macOS 有 内存压缩器:当内存吃紧时,内核把一些不常用的页在内存里压缩,而不是写到磁盘。这相当于“swap 到内存里”,比落盘快得多,也不伤闪存。

所以你会在 Instruments / vm_stat 里看到 compressor 相关的统计。这是 iOS 在没有 swap 的情况下,仍然能腾出空间的重要手段。

③ App 主动释放 / 系统回收

  • App 收到内存警告(didReceiveMemoryWarning)应主动释放缓存。
  • 系统回收可清除的缓存(如 NSCache、图片缓存)。

5. 所以那句话准确吗?

iOS 没有内存交换分区(swap),内存紧张时内核的 jetsam 机制会按优先级杀进程释放内存。

准确,但可以补一句:iOS 虽然没 swap,但有内存压缩作为缓冲,压缩也不够时才轮到 Jetsam 杀进程。完整链路是:

内存压力上升
  → 释放可清除缓存
  → 内存压缩(compressor)
  → 仍不够:Jetsam 按优先级杀进程

小结

  • swap 分区:把内存页写到磁盘/闪存,用磁盘换内存,Linux/macOS/Windows/Android 都有。
  • iOS 没有 swap:因为闪存寿命、功耗、延迟,以及移动端“前台优先、后台可杀”的模型。
  • iOS 的替代方案:内存压缩 + Jetsam 杀进程 + App 主动释放。
  • Jetsam 和 Watchdog 是两回事:前者因内存压力杀进程,后者因超时杀进程。