西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页 → 业内动态 → 业内资讯 → swap到底是什么:一块交换分区怎么把4G内存扛住12G的任务

swap到底是什么:一块交换分区怎么把4G内存扛住12G的任务

相关软件相关文章发表评论 来源:本站整理时间:2026/11/2 16:21:48字体大小:A-A+

  • 类型:安卓其它大小:29.0M语言:中文 评分:10.0
  • 标签:
立即下载

上周三凌晨两点多,值班手机把我震醒,告警群里全是「接口大面积超时」。登录堡垒机一看,机器没重启、CPU 也没打满,唯一的异常是业务进程莫名其妙少了一个,dmesg 里躺着一行 Out of memory: Killed process 12841 (java)。这台 4G 内存的机器,跑着一个堆内存给到 3G 的 Java 服务,再加一个 MySQL 实例,内存自然就见底了。

服务器内存老是跑满、进程被杀,swap 到底该不该加、怎么加?宝塔助手(Linux运维)(服务器运维工具,v1.4.1)能直接在手机上查看各台机器的内存、负载和进程占用排行,面板里也能一键重启异常服务、调服务自启策略,不用每次都开 SSH 敲命令再逐个机器排查,盯着的机器一多,这个工具能省下不少时间。

那天我没有直接升配(升配要提工单、要走审批,当天不一定能下来),而是先把 swap 加上应急。第二天复盘的时候我才想明白:swap 这玩意儿不是「内存不够时的万能补丁」,它有明确的适用场景,也有一堆坑。下面这段时间我把 swap 的原理、开启步骤、参数含义和翻车点全部整理出来,帮你少走几遍弯路。

Linux服务器终端中查看内存占用与swap使用情况的命令输出

一、先分清:是内存不够,还是程序漏了

很多人一看内存 95% 就开始加 swap,其实这一步就错了。内存使用率高有两种完全不同的病根:一种是业务量涨了,内存确实不够,属于「量的问题」;另一种是程序自己泄漏了,内存只涨不降,属于「病的问题」。加 swap 对第二种基本没用你只是把泄漏的速度变慢了。

判断的第一步是看有没有被 OOM Killer 干掉过。杀进程之前内核会留证据:

dmesg -T | grep -i -E "out of memory|killed process"

有输出,说明确实是被内核动过手,而且能看到被杀进程的 PID 和名字。注意一点:被杀的通常不是罪魁祸首,而是「当时占用内存最多的那个倒霉蛋」。可能是你的 Java 服务,也可能是隔壁跑着的某个缓存进程。

第二步看内存的构成。直接上手 free -h 容易被 buff/cache 那几行绕晕,建议直接看这几个指标:

free -h
cat /proc/meminfo | grep -E "MemAvailable|SwapTotal|SwapFree|Cached"

其中 MemAvailable 才是「你还能再分配多少」的参考值,不是 MemFree。很多人在 free 只有 200M 时慌了神,结果 MemAvailable 还有 3G,白紧张一场。

第三步看内存到底被谁吃了:

ps aux --sort=-%mem | head -15
cat /proc/$(pgrep -f your_app | head -1)/status | grep VmRSS

如果某个进程的 RSS 曲线是「只涨不落」,那基本可以确定是泄漏或者缓存没有设上限;如果是随着请求量有涨有落,那就是正常的量的问题。加 swap、限流、升配这三招,对第一种有意义,对第二种只能靠改代码。

二、swap 到底是什么,它凭什么能救场

swap 是内核在物理内存不够时,把一部分暂时用不到的内存页换到磁盘上的那块空间里。你可以在 Linux 里把它理解成一块「超慢速内存」:读的时候要经过磁盘 IO,延迟比内存高好几个数量级。

内核的换页策略是惰性换出它优先把很久没访问的冷页面丢到 swap,把热页面留在物理内存里。这解释了一个常见现象:明明加了 swap,机器内存占用率还是很高,因为内核觉得那些页面「还有用」,不肯换。所以 swap 起作用的前提是内存压力足够大、触发了回收。

也正因为它慢,swap 的价值在于:它能把「进程直接被杀掉」变成「进程变慢但还活着」。对于偶发流量尖峰、批量任务、编译打包这类场景,加 swap 能让服务扛过峰值,不至于半夜被 OOM 直接干掉。这是它最大的价值,也是我那天晚上最需要的。

但反过来说,如果你给一个要求低延迟的接口服务加 swap,内存紧张时它会把响应时间从几十毫秒拖到几百毫秒甚至几秒接口从「偶尔超时」变成了「一直偏慢」,用户体验未必更好,还容易在监控上被误判成网络问题。所以 swap 和延迟敏感型服务,天生是一对需要取舍的关系。

固态硬盘与交换分区设备的抽象概念示意图

三、手把手加 swap:一条命令级别的实操

云服务器一般用 swapfile 的方式,不用分区,开起来快、也容易撤。下面是完整流程,我实测过多次:

# 1. 看看现状:有没有 swap、用了多少
free -h && swapon --show

# 2. 创建一个 4G 的 swapfile(大小按物理内存的 25%~50% 给,别超磁盘剩余空间)
fallocate -l 4G /swapfile

# 3. 权限必须只给 root,否则内核拒绝挂载
chmod 600 /swapfile

# 4. 格式化成 swap 并启用
mkswap /swapfile
swapon /swapfile

# 5. 写进 fstab,重启后自动挂载
echo "/swapfile none swap sw 0 0" >> /etc/fstab

第 3 步的 chmod 600 是最容易踩的一个坑。很多人 chmod 777 /swapfile 想着「宽松点好」,结果 swapon 直接报 Permission denied因为内核出于安全考虑,只允许 root 访问 swap 文件。

另外注意 fallocate 在某些文件系统(部分 NFS、某些云厂商的特殊磁盘)上创建的稀疏文件会有问题。如果 swapon 报 Invalid argument,改用 dd if=/dev/zero of=/swapfile bs=1M count=4096 就行,我在一台 NFS 挂载的机器上踩过这个坑。

四、swappiness 这个参数,决定了它有多容易被用上

系统刚装好时,vm.swappiness 默认值一般是 60,意思是「内存占用超过 60% 就开始积极把页面换到 swap」。这个默认值对数据库、Redis 这类重内存服务往往偏激进你可能不希望它们的数据页被换到磁盘上。

常见的三档取值和适用场景:

60(默认):通用服务器,内存和 swap 都有富余时没什么问题;
10~20:数据库、Redis、ES 等重缓存服务,尽量把内存留给热数据,只在快撑不住时才换;
0:基本等于禁用 swap,内存不够就直接触发 OOM,适合内存充足且更怕延迟波动的机器。

临时调整用 sysctl -w vm.swappiness=10,永久生效就写进 /etc/sysctl.conf 并执行 sysctl -p。改完记得用 vmstat 1 观察 si(swap in)和 so(swap out)两列:只要 so 持续不为 0,说明磁盘正在被换出动作打满,这时候如果业务对延迟敏感,就该考虑升配而不是继续调参了。

运维人员在多显示器前排查服务器内存告警

五、别踩这几个坑

坑一:以为加了 swap 就等于多了内存。swap 容量建议按物理内存的 25%~50% 设置。设成和物理内存一样大看着豪爽,但真跑起来磁盘 IO 会被打满,服务反而更慢。

坑二:容器里以为加了 swap 就安全。现在的 Docker/K8s 环境,容器有独立的 cgroup 内存上限。你在宿主机上加的 swap,容器是用不到的容器超限会被 cgroup 直接杀掉,日志里是 OOMKilled 而不是内核的 Killed process。检查方法:

docker inspect -f '{{.State.OOMKilled}} {{.HostConfig.Memory}}' 容器名
docker stats --no-stream

坑三:swapfile 没写进 fstab。手动 swapon 只是临时生效,机器一重启就原样消失,然后你就接到第二次告警。改完 fstab 后一定要 mount -a 验证一下语法,别等重启才发现。

坑四:用 swap 掩盖泄漏。内存曲线只涨不落,加多少 swap 都填不满。真正该做的是找出那个只涨不落的进程,给它加上内存上限或者直接升级代码。

六、什么时候该直接升配,而不是加 swap

经验上,swap 适合当「救火绳」而不是「长期方案」。下面这几种情况,我会直接走升配流程:

常驻内存已经贴着物理内存跑,加 swap 只是把崩溃变成变慢;
业务对延迟敏感,接口 P99 有硬指标,不能接受几百毫秒的抖动;
是数据库、Redis 这类靠内存换性能的服务,swap 一开性能就塌;
磁盘是低 IO 的云盘,换出动作一上来,整台机器的 IO 都被拖住。

如果只是偶尔有个批处理任务把内存顶高,或者临时活动带来流量尖峰,那加 swap + 适当调低 swappiness,基本就是性价比最高的应急手段。

七、一份排查速查表

下次再遇到「服务莫名重启/消失」,按这个顺序走一遍基本能定位:

dmesg -T | grep -i "killed process" # 1. 确认是否 OOM
free -h # 2. 看 MemAvailable 和 swap 使用量
vmstat 1 5 # 3. 看 si/so 是否持续非零
ps aux --sort=-%mem | head # 4. 揪出吃内存的大户
cat /sys/fs/cgroup/memory.max # 5. 容器环境确认 cgroup 上限

最后补一句我的真实体会:swap 是给「内存不够」打的补丁,不是给「代码有 bug」打的补丁。真正省事的做法,是在上线前就把内存基线、峰值和告警阈值定好,别等凌晨两点让 OOM Killer 帮你做测试。

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶顶
    • 1 难过难过
    • 5 囧囧
    • 3 围观围观
    • 2 无聊无聊

    发表评论

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲