先直接回答:iOS 确实没有传统意义上的 swap 分区。有 swap 的典型代表是桌面 Linux、macOS、Windows,以及 Android(严格说是 zram 压缩交换,但机制上属于交换的一种)。
下面把"swap 分区是什么、谁有、iOS 为什么没有、没有的话靠什么"讲清楚。
1. swap 分区是什么?
swap(交换空间) 是操作系统在磁盘/闪存 上划出的一块区域,用来存放内存里暂时不用的页(page)。
工作逻辑:
- 物理内存(RAM)不够用了。
- 内核挑选一些"最近不常用"的内存页。
- 把这些页写到磁盘上的 swap 区,然后在 RAM 里腾出空间。
- 以后某个进程再访问这些页时,触发缺页异常(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 是两回事:前者因内存压力杀进程,后者因超时杀进程。