为什么 zram 会产生“碎片”?【用前文提到的脚本已经加入自动清理】
虽然 zram 运行在内存中,但它本质上是一个块设备。产生碎片的原因主要有两点:
- 压缩块的大小不一:内存被划分为固定大小的“页”(Page,通常是 4KB)。当你把数据压缩后,有的页变成了 1KB,有的变成了 2KB。zram 使用名为
zsmalloc的分配器将这些不规则的“压缩块”塞进物理内存页中。 - 数据的频繁换入换出:随着系统运行,老的压缩数据被释放,新的数据存入。如果分配器不能完美地填补之前释放留下的细小空隙,就会产生外部碎片。
- 内存不可移动性:在某些情况下,由于
zsmalloc的设计,它不能像整理磁盘碎片那样轻易地移动已经存储的压缩数据块。
结果就是:zramctl 里的 TOTAL(实际占用物理内存)会比 COMPR(压缩后的数据大小)大得多。这多出来的部分就是被浪费掉的碎片空间。
定时清理与优化脚本
对于内存受限的系统(如你的 300MB 或 2GB 小鸡),我们可以通过以下脚本进行定期维护。
1. 核心命令:compact(压缩整理)
现代 Linux 内核为 zram 提供了一个 compact 节点。向它写入 1,内核就会尝试重新排列物理内存页中的压缩块,以减少碎片。
2. 自动化维护脚本
你可以将以下脚本保存为 /usr/local/bin/zram-optimize.sh:
#!/bin/bash
# zram 碎片整理与优化脚本
# 1. 触发内核层面的 zram 压缩整理 (Memory Compaction)
if [ -f /sys/block/zram0/compact ]; then
echo "正在执行 zram0 碎片整理..."
echo 1 > /sys/block/zram0/compact
echo "整理完成。"
else
echo "当前内核不支持 zram 自动整理。"
fi
# 2. 触发系统级内存回收 (可选,慎用)
# 这一步会强制内核检查哪些内存可以被进一步压缩进 zram
# sync && echo 1 > /proc/sys/vm/drop_caches
# 3. 输出当前效率报告
echo "--- 当前 zram 状态 ---"
zramctl --output NAME,DATA,COMPR,TOTAL,STREAMS
3. 设置定时任务 (Crontab)
建议每天凌晨 3 点自动运行一次,这样可以保持系统长期稳定运行。
在 Debian/Alpine 中操作:
- 输入
crontab -e - 在文件末尾添加以下一行:
0 3 * * * /bin/bash /usr/local/bin/zram-optimize.sh > /dev/null 2>&1
总结:有必要担心吗?
- 对于 2GB 的 VPS:碎片问题通常不明显,因为
zsmalloc已经足够高效,通常只有在运行数月不重启的情况下,碎片才会浪费掉几十 MB 内存。 - 对于 300MB 的极限小鸡:碎片非常致命。因为你的总内存太少了,哪怕 20MB 的碎片浪费,都可能导致系统触发 OOM(内存溢出)错误。
执行完这个脚本后,你可以再次运行 zramctl,观察 TOTAL 这一列的数值是否有所下降,那就是被回收的碎片空间。