Linux 内存不足?ZRAM 压缩方案详解与实战配置

Linux 设备内存不够用是常态,尤其是小内存 VPS、树莓派、旧笔记本等场景。传统做法是加 SWAP 分区,但很多人发现加了之后反而更卡了。

这篇文章从底层原理出发,对比 SWAP 和 ZRAM 两种方案,帮你搞清楚:什么场景该用什么,以及怎么配置。

SWAP 的工作原理很简单 — 内存放不下的数据写到磁盘上,需要时再读回来。问题出在「磁盘」这两个字上。

磁盘 IO 和内存 IO 的差距是数量级的:

操作延迟
内存访问~100 纳秒
SSD 随机读~100 微秒(慢 1000 倍)
HDD 随机读~10 毫秒(慢 100000 倍)

这意味着当系统开始频繁使用 SWAP(所谓的 swap thrashing),进程会频繁被阻塞等待磁盘 IO,系统表现就是:卡顿、假死、鼠标能动但点啥都没反应。

而且 SWAP 对 SSD 还有副作用 — 频繁的写入会加速闪存颗粒磨损(虽然现代 SSD 寿命已经很长了,但在高 SWAP 负载下依然不可忽视)。

SWAP 适合的场景:

  • 磁盘是 NVMe SSD,IO 延迟足够低
  • 内存基本够用,SWAP 只是偶尔的应急缓冲
  • 不在意偶尔的卡顿,只要不 OOM(Out of Memory)被杀进程

SWAP 不适合的场景:

  • 磁盘是 HDD 或低速 eMMC
  • 内存经常吃紧,SWAP 会成为常态而非应急
  • 需要稳定低延迟的服务(数据库、API 服务)

ZRAM 完全不碰磁盘。它在内存中创建一个压缩块设备,把不常用的内存页压缩后存放。需要时解压还原。

核心优势:

  1. 数据始终在内存中 — 没有磁盘 IO 瓶颈,延迟是微秒级
  2. 压缩比通常 2:1 ~ 3:1 — 1GB 物理内存可以当 2~3GB 用
  3. 对 SSD 友好 — 减少磁盘写入,延长寿命

隐性代价:

  • CPU 开销:压缩和解压需要 CPU 计算。lz4 算法已经很轻量了,但在 CPU 本身就是瓶颈的设备上(极低端的 ARM 芯片),还是会有影响
  • 不能无限压缩:物理内存耗尽后 ZRAM 也救不了你,仍然需要 SWAP 兜底

不要简单地说「磁盘差就用 ZRAM」,应该根据实际情况分层决策:

你的磁盘是什么类型?
├── 纯 NVMe SSD
│   ├── 内存基本够用(偶尔不足)→ SWAP 足矣
│   └── 内存经常紧张 → ZRAM 优先 + 小容量 SWAP 兜底
├── 纯 SATA SSD
│   └── 推荐 ZRAM 为主 + 小 SWAP 兜底
├── SSD + HDD 混装
│   └── ZRAM 为主,SWAP 放 SSD(不放 HDD)
├── 纯 HDD / eMMC
│   └── 必须用 ZRAM,尽量不用 SWAP
└── VPS(云盘通常 IO 较好)
    └── ZRAM 为主,可加小 SWAP 防止 OOM

总结一句话:磁盘越差,ZRAM 越重要;内存越小,ZRAM 越必要。

sudo apt update && sudo apt install -y zram-tools

编辑配置文件:

sudo nano /etc/default/zramswap

填入以下内容:

ALGO=lz4          # 高速压缩算法,兼顾速度与压缩率
PERCENT=50        # 占用物理内存的 50% 作为 ZRAM 空间
PRIORITY=100      # 优先使用 ZRAM,优于磁盘 SWAP

PERCENT 怎么定?

物理内存建议 PERCENT说明
≤ 512MB100%内存太小,压缩空间越多越好
1GB ~ 2GB75% ~ 100%根据负载调整
4GB ~ 8GB50%平衡压缩空间和可用内存
> 8GB25% ~ 50%通常够用,不需要激进压缩

注意:PERCENT 不是越大越好。ZRAM 本身占用物理内存,设太高会挤压正常程序的可用内存,反而加重内存压力。50% 是一个比较安全的起步值,可以根据实际使用情况调整。

sudo systemctl enable --now zramswap.service
swapon --show

看到 /dev/zram0 即成功:

NAME       TYPE      SIZE USED PRIO
/dev/zram0 partition  XXX   0  100
zramctl

输出示例:

NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4         XXXG  XXXM  XXXXX  XXXXX       N  [SWAP]

关注 DATA(原始数据大小)和 COMPR(压缩后大小)的比例,这就是实际压缩比。

更详细的统计:

cat /sys/block/zram0/mm_stat

ZRAM 虽好,但物理内存终究有限。当压缩后的数据也塞不下时,系统会 OOM。建议 ZRAM + 磁盘 SWAP 混合使用,通过 PRIORITY 控制优先级:

  • PRIORITY=100 的 ZRAM 作为第一层 — 常规内存压力由它吸收
  • PRIORITY=10 的磁盘 SWAP 作为兜底 — 极端情况防止 OOM

这样系统会先用 ZRAM(快),ZRAM 满了才慢慢溢出到磁盘 SWAP(慢但不会死)。

如果你之前已经有 SWAP 分区,不需要删掉,ZRAM 的 PRIORITY 设高就行,内核会自动按优先级选择。

Q:ZRAM 会占用我的可用内存吗?

是的。ZRAM 设备本身预分配一部分内存。但这是用少量内存换取更大的压缩空间,净效果是正的。以 50% 比例为例,2GB 内存的设备会划出 1GB 做 ZRAM,但压缩后等效于 2~3GB 的 SWAP 空间,总体可用内存是增加的。

Q:ZRAM 会导致 CPU 占用升高吗?

会有小幅增加,lz4 算法的 CPU 开销非常低。在树莓派 4 这种 ARM 设备上测试,SWAP 操作期间的 CPU 额外占用通常在 3%~8%。只有在极端高频内存操作场景下才需要关注。

Q:我该不该关掉原来的 SWAP?

通常不需要。保留原有 SWAP 并设低优先级即可,让 ZRAM 优先处理。如果你的磁盘是 HDD,可以考虑缩小或关闭 SWAP,避免频繁的磁盘写入。

Q:压缩算法选 lz4 还是 zstd?

日常使用选 lz4,压缩/解压速度极快,延迟最低。如果内存极其紧张(如 256MB 设备),可以考虑 zstd,压缩比更高(约比 lz4 高 20%~30%),但 CPU 开销更大。对于大多数场景,lz4 是最优选择。

相关内容