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   swap

2. 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,说明该升级内存了。