Swap 技术详解
一、计算机内存的基本概念
要理解 Swap,先要理解计算机里几种存储的区别:
速度: 寄存器 > 内存(RAM) > SSD > 机械硬盘
容量: 寄存器 < 内存(RAM) < SSD < 机械硬盘
价格: 寄存器 > 内存(RAM) > SSD > 机械硬盘
内存(RAM) 是程序运行时的”工作台”,所有正在运行的程序都必须加载到内存里才能执行。它的特点是速度极快,但断电后数据消失,且容量有限、价格贵。
二、为什么需要 Swap?
没有 Swap 的世界
物理内存: [程序A:200MB][程序B:300MB][程序C:400MB] = 900MB 已用完
新程序D 需要 200MB → 没地方放 → 直接 OOM Killed(被系统强制杀死)
OOM = Out Of Memory,就是你之前看到的:
FATAL ERROR: JavaScript heap out of memory
有 Swap 的世界
物理内存: [程序A:200MB][程序B:300MB][程序C:400MB] = 900MB 已用完
新程序D 需要 200MB →
系统:把程序A暂时挪到硬盘上的Swap区
物理内存: [程序B:300MB][程序C:400MB][程序D:200MB]
程序A的数据: 安全躺在硬盘Swap区,需要时再换回来
→ 所有程序都能运行,不崩溃 ✅
三、Swap 的工作原理
换入换出机制(Paging)
┌─────────────────────────────────────────┐
│ 物理内存 RAM │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 程序A │ │ 程序B │ │ 程序C │ │
│ │ 活跃中 │ │ 活跃中 │ │ 长时间 │ │
│ │ │ │ │ │ 没用了 │ │
│ └────────┘ └────────┘ └───┬────┘ │
└──────────────────────────┬──────────────┘
内存不够时│ swap out(换出)
▼
┌─────────────────────────────────────────┐
│ 硬盘 Swap 区 │
│ ┌────────┐ ┌────────┐ │
│ │ 程序C │ │ 程序D │ ← 暂时存放 │
│ │(已换出)│ │(已换出)│ │
│ └────────┘ └────────┘ │
└─────────────────────────────────────────┘
需要时 swap in(换入)↑
操作系统的内存管理模块(MMU)会追踪哪些内存页面”最近最少使用”(LRU算法),把不活跃的页面换出到 Swap,给活跃程序腾空间。
四、Swap 的两种形式
1. Swap 分区
在磁盘上划出一个独立分区专门用作 Swap,格式化时就确定大小,之后无法动态调整。
# 查看是否有swap分区
lsblk
# 显示类似:sda2 swap2. Swap 文件(你用的这种)
在普通文件系统上创建一个文件,更灵活,可以随时调整大小:
# 你的swap文件位置
/www/swap # 4GB的普通文件,被当作swap使用两者性能几乎相同,Swap 文件更灵活,现代 Linux 都推荐用这种方式。
五、关键参数:swappiness
swappiness 是控制系统”多积极地使用Swap”的参数,范围 0~100:
# 查看当前值
cat /proc/sys/vm/swappiness
# 常见设置:
vm.swappiness=0 # 几乎不用swap,内存快用完才用(数据库服务器推荐)
vm.swappiness=10 # 保守使用swap(生产服务器推荐)
vm.swappiness=40 # 你现在的设置,适中
vm.swappiness=60 # 系统默认值
vm.swappiness=100 # 积极使用swap我们给你设置的是 40,比默认值更保守一点,优先用物理内存,swap只作为缓冲。
六、Swap 的缺点
速度差距巨大
内存读取速度: ~50,000 MB/s
SSD Swap速度: ~500 MB/s ← 慢100倍
机械硬盘Swap: ~100 MB/s ← 慢500倍
Swap 风暴(Thrashing)
这就是你今天遇到的情况!当内存严重不足时:
内存不够 → 大量换出到Swap
程序需要数据 → 从Swap换回内存
换回来又没地方 → 再换出其他数据
循环往复 → 磁盘IO爆满 → iowait 90%+ → 系统假死
这就是为什么今天你看到:
- CPU只有6% → CPU在等硬盘,不是真正在计算
- iowait高达93% → 几乎所有时间都在等磁盘读写
- 负载100% → 大量进程堵在IO等待队列里
七、今天我们做了什么,为什么有效
问题根源
爬虫占用 60% 内存 + openclaw 占用 30% = 内存耗尽
→ Swap只有1GB也满了
→ 系统开始Swap风暴
→ 磁盘IO爆满 → 系统假死
解决步骤
步骤1:杀掉爬虫 → 释放60%内存,Swap风暴停止
步骤2:清理内存缓存 → 进一步释放内存
步骤3:扩大Swap到4GB → 给openclaw足够的缓冲空间
步骤4:限制Node.js堆内存 → 防止openclaw无限制占用内存
八、最佳实践总结
| 场景 | Swap建议 |
|---|---|
| 内存充足的生产服务器 | 设置少量Swap(内存的25%)作为应急 |
| 内存紧张的小服务器(你的情况) | 设置较大Swap(内存的2~4倍) |
| 数据库服务器 | 尽量不用Swap,swappiness=0~10 |
| 桌面电脑 | 默认设置即可 |
记住一句话:Swap 是保命用的,不是用来弥补内存不足的长期方案。 如果服务器长期大量使用 Swap,说明该升级内存了。