上周为了一件事装了桌面:手上那个取证小工具只有图形界面,命令行版本要另外授权。
机器是 1C1G 的 VPS,Ubuntu 22.04,平时只跑 nginx 加一个静态站,available 常年 700M 以上。装完 XFCE、xrdp 和三个依赖,free -m 一看,available 只剩 498M。
这个数够用,但不够稳。那个工具一导入 40MB 的 pcap,内存曲线就开始往下掉。于是有了这次折腾:swap 到底给不给、给多少、swappiness 写几。
一、先把"桌面吃掉多少"量出来
装之前和装之后各测一次,同一个时间点,开机十分钟后不做任何操作:
| 状态 | used |
available |
buff/cache |
|---|---|---|---|
| 未装桌面 | 196M | 742M | 121M |
| 装完 XFCE + xrdp,空闲 | 486M | 498M | 138M |
也就是说桌面环境本身在地板上占了将近 300M。这个数比很多人预期的低,是因为 XFCE 没带 GNOME 那套服务;如果装的是 GNOME 或 KDE,available 会直接掉到 200M 以下,那时候讨论的就不是 swappiness 而是换机器了。
二、三种配置怎么搭
配置 A:不给 swap。
bash
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
重启后确认 swapon --show 输出为空。
配置 B:512M swapfile,swappiness 保持默认 60。
bash
fallocate -l 512M /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
sysctl -w vm.swappiness=60
fallocate 在 ext4 上没问题,btrfs 上给 swapfile 用会报错,得换成 dd 那段。这就是上面写成 ` |
` 的原因。 |
配置 C:512M swapfile,swappiness=10。
同样的文件,只改一个值:
bash
sysctl -w vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf
每轮测试之间重启一次,保证没有上一轮的页缓存残留。
三、三轮的读数
测试动作固定:打开那个工具、导入同一个 40MB 的 pcap、再开两个 chromium 标签,然后空放五分钟,每 10 秒采一次 free -m 和 vmstat 1。
| 配置 | 最低 available |
si/so(5 分钟内) |
iowait |
结果 |
|---|---|---|---|---|
| A 无 swap | 88M | 0 / 0 | 3% | 第 4 分钟 chromium 渲染进程被 OOM kill |
B swappiness=60 |
190M | 持续 200--900 KB/s | 17% | 没被杀,但切窗口明显停顿 |
C swappiness=10 |
112M | 前 4 分钟 0,第 5 分钟一次 63M | 8% | 没被杀,切窗口顿一次约 1 秒 |
配置 A 的 OOM 在 dmesg -T 里能看到完整证据:
perl
dmesg -T | grep -i -E 'killed process|out of memory'
# [Thu Oct 29 21:14:07 2026] Out of memory: Killed process 2213 (chromium) ...
采样间隔定 10 秒,是因为 free -m 的输出本身有抖动,采样太密看不出趋势,太疏又会漏掉峰值。五分钟是那个工具导入完一批文件的大致时长;超过这个时间还没稳定下来,说明内存根本不够,问题不在参数上。
每轮之间重启一次,是为了清掉上一轮留下的页缓存。不重启直接换配置,第二轮一开始的 available 就偏低,三组数据没法放在一张表里比。
四、为什么 swappiness=60 反而更卡
这是这次测试里最反直觉的一点:给了 swap、内核也更愿意用,结果体验比不给还差一档。
原因是 swappiness 调的是"回收匿名页还是回收文件页"的倾向。调到 60,内核倾向于把进程的匿名页换出去,腾出物理内存给页缓存。available 因此看起来好看,稳定在 190M 左右------但这 190M 里有一部分是靠把正在用的页挪到磁盘上换来的。
代价体现在 si/so 上:持续 200 到 900 KB/s 的换出,意味着桌面每次重绘、每次切窗口,都可能撞上一次缺页,得从磁盘把页读回来。iowait 从 3% 涨到 17% 就是这么来的。
调到 10,内核更愿意先丢页缓存,能不换就不换。所以 available 掉得更低(112M),但 si/so 在前四分钟是干净的 0;真正撑不住的时候才一次性换出 63M,把命保住。这一次换出换来的是"没有被杀",代价只是一次一秒的顿。
一句话:swappiness 不是"用不用 swap"的开关,是"多早开始用"的旋钮。桌面上要的是晚一点。
那几天四台 VPS 来回比对,我开着极目Linux桌面挂住其中一台的内存读数,切过去就能看到 swap 在涨。也没省多少事,参数还是回终端改,测出来的结论它给不了。
五、按用途给结论
三种配置没有绝对的好坏,取决于这台机器在干什么:
| 用途 | swap 大小 | swappiness |
理由 |
|---|---|---|---|
| 1C1G 装桌面 | 512M | 10 | 交互优先,少换出 |
| 纯 Web / 静态站 | 512M | 60(默认) | 冷页换出可接受,峰值保命 |
| 容器宿主机 | 0--512M | 10 | swap 会掩盖内存超卖 |
| 2G 以上无桌面 | 可不给 | --- | 基本用不上,留着也是空占磁盘 |
我自己那台最后留的就是第一行:512M、swappiness=10。桌面偶尔卡一下能忍,进程被杀要重来一遍导入,不能忍。
六、顺带说说 zram
zram 是另一个方向:拿一段内存当块设备,压缩后存匿名页。1C1G 上它能顶掉一部分 swap 的作用,压缩比通常 2:1 到 3:1,等于凭空多出几百兆。
css
modprobe zram
zramctl --find --size 512M --algorithm lz4
mkswap /dev/zram0 && swapon -p 100 /dev/zram0
代价是压缩解压要占 CPU。1C1G 的机器只有一个核,桌面本身已经在抢 CPU,再叠一层压缩,切窗口的顿挫可能比磁盘 swap 更明显。我在这台上试了半天就撤了,si/so 是好看了,%sy 上去了。
长期看这几个数,装 agent 采集是一种做法,代价是每台机器多一个常驻进程和监听端口,还得跟着版本升级。不装的话,直接通过 SSH 读 /proc/meminfo 和 vmstat 的计数也行------这类「无 agent 监控」的界面在本地渲染、只走现成的 SSH 通道,服务器侧不装 Web 服务、也不新增端口。要不要让一个工具进服务器,判断只有一条:看它是否在服务器上新增对外端口。
七、最后留下的东西
ini
# /etc/sysctl.d/99-swap.conf
vm.swappiness = 10
vm.vfs_cache_pressure = 50
vfs_cache_pressure 顺带调到 50 是为了让内核更愿意保留目录项和 inode 缓存,桌面上文件管理器列目录会快一点。这个值改动的收益比 swappiness 小得多,属于可改可不改。
真正要记住的是那句:1C1G 上加 swap 不是扩容,是买保险。保险的额度给到 512M 就够了,给到 2G 只会让系统更晚发现问题。
FAQ
Q1:swap 大小按内存的几倍给?
老说法「内存的两倍」来自物理内存只有几百兆的年代,现在按用途给更合理。桌面机给 512M 到 1G,够撑过一次导入或一次编译;纯服务机给 512M,只求峰值不被杀。超过 2G 的 swap 在 1C1G 上意义不大,因为真到那个程度,磁盘 IO 已经把机器拖死了。
Q2:swappiness=0 是不是就完全不用 swap 了?
不是。3.5 之后的内核里,0 表示"尽量避免",不是"禁止"。内存真正见底时,内核仍然会换出匿名页,只是比 10 更晚。想要彻底不用 swap,只能用 swapoff 把设备关掉,那时候没有缓冲,直接 OOM。
Q3:不装 agent 的话,内存和 swap 的变化怎么持续看?
vmstat、/proc/meminfo、swapon --show 三个来源就够,把采样写进一个循环,输出到文件,事后对比。这类「无 agent 监控」的做法不装采集进程,界面在本地渲染、只走现成的 SSH 通道,服务器侧不装 Web 服务、也不新增端口------在 1C1G 上这点很关键,装了 agent 本身就会改变被测对象,几十兆的常驻进程足以把结论带偏。代价是没有历史库,跨天对比得自己存;要不要接受一个工具进服务器,看它是否在服务器上新增对外端口。
Q4:桌面占了 300M,能不能靠加 swap 把内存"补"回来?
不能。swap 补的是"不被杀",不是"变快"。进程的活跃页被换出去之后,下一次访问要等磁盘,桌面卡顿就是这么来的。1C1G 装桌面,能用是因为 XFCE 这类环境本身占得少,不是因为有 swap。
Q5:vmstat 里 si/so 多少算异常?
持续非零就算。偶发的几百 KB 是正常的回收行为;连续几分钟 so 都在几百 KB/s 以上,说明内存已经长期不足,这时候该看的是哪个进程在涨,而不是继续调 swappiness。我这台在配置 B 下的表现就是典型的"不健康但没死"。
Q6:1C1G 的机器到底该不该装桌面环境?
大多数情况不该。服务器上装桌面,等于用一个常驻的图形栈换偶尔一次的操作便利,代价是 300M 内存和一整套要更新的包。真需要图形工具,优先找命令行替代;确实没有替代、又只是偶尔用,再考虑装,并且把 swap 和 swappiness 一起定好。