news 2026/10/2 5:28:26

Linux Swap释放与调优实战:安全清理内存交换分区的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux Swap释放与调优实战:安全清理内存交换分区的完整指南

1. Swap被占满的常见场景:什么时候需要动手

先说结论:swap本身不是洪水猛兽,它只是内存和磁盘之间的次级缓存层。Linux内核在物理内存(RAM)不足时,会把一部分不常用的内存页挪到磁盘上的swap分区或swap文件中,腾出RAM给活跃进程用。这个机制本身没有任何问题,问题出在两种操作场景下,你会特别想“清一清”它。

第一种场景是服务进程内存吃紧后把swap撑满。比如你跑了个Java应用、MySQL实例或者编译大型C++项目,内存峰值冲上去之后,swap被大量写入。等进程退出、内存释放后,swap上的那些页就成了“死数据”,它不会自动被换回RAM,只会一直躺在磁盘上,直到被再次访问或系统重启。这时候你执行free -h,会看到Swap这一行的used值仍然很高,明明物理内存明明很充足,swap却毫无必要地占据着。

第二种场景是系统监控告警触发,强迫症发作。我接过不少朋友的求助,他们的云服务器就2GB内存,跑了个Node服务经常触发swap使用率告警,他们第一反应是“把swap清掉”。这里要泼一盆冷水:如果物理内存长期不足,你去清swap,系统会立刻重新把数据换入RAM,然后很快再次换出,造成频繁换页(thrashing),性能反而更差。真正该做的是升级内存、优化进程参数或者显式限制某些服务的内存用量。清swap只适用于“流量高峰已经过去、当前物理内存余量充足”的窗口期。

所以,适合动手清swap的前提条件很简单:物理内存(可用部分)大于swap当前使用量,系统负载正常,磁盘没有告警。满足这三个条件后再往下操作,你会很从容。

2. 释放swap的核心原理:为什么不能直接“卸载”

很多新手第一次搜到“释放swap”,看到的第一条建议是swapoff -a——把swap整体关掉再打开。这样做确实能把swap里的数据全部换回物理内存,代价是:swapoff会在操作期间尝试把swap上的所有页都换回RAM,如果RAM不够大,内核会进入内存回收流程,甚至触发OOM Killer杀进程。所以在物理内存不够的时候执行swapoff -a,是会死人的。

更稳妥的思路有两个。一个是用sysctl vm.swappiness调整内核的换页偏好,减少未来swap写入;另一个是上面说的“卸下再挂载”,但要先确认内存余量。

另外很多资料里提到的swapoff /dev/sda2 && swapon /dev/sda2,本质上就是让swap设备短暂“消失”再“重现”。只要内存足够,内核会把swap上的页全部换入RAM,然后重新挂载swap设备,此时swap的used基本归零。这套操作在RHEL系、Debian系和Ubuntu上都是通用的,唯一的差别是swap设备的命名方式和是否需要修改/etc/fstab。

2.1 区分swap分区与swap文件

在动手前,要先搞清楚机器的swap到底是什么形式。多数传统服务器用的是独立分区,比如/dev/sda2;但云主机、容器环境里越来越常见的是swap文件,比如/swapfile。两者在释放操作上几乎一样,但查看命令略有差别。

查看当前swap配置:

swapon --show

输出大致长这样:

NAME TYPE SIZE USED PRIO /dev/sda2 partition 2G 1.2G -2

如果是文件型swap,NAME一栏会显示文件路径。还有一种是ZRAM,属于内存压缩型swap,它的“释放”逻辑和磁盘swap完全不同,不能简单用swapoff处理——ZRAM的used高不代表磁盘空间被占用,所以也不需要刻意释放。这里先提醒一下,后面再展开。

2.2 swapiness参数不是用来“清空”的

vm.swappiness控制的是内核“多积极”地使用swap,取值范围0到100。数值越低,内核越倾向于保留物理内存中的匿名页,更少写入swap;数值越高,越愿意提前换出页面。但它是一个偏好阈值,不是你执行sysctl之后swap就被清空的开关。把这个参数调低,可以降低未来swap被塞满的概率,但对已存在的swap数据没有任何清理作用。

想要真正释放已占用的swap,核心操作还是swapoff这一条路,swappiness最多只能帮你“治未病”。

3. 安全释放swap的完整操作步骤

下面这套流程,我自己的生产环境里跑过很多次,也帮好几个读者远程解决过告警。核心原则就一句话:先确认内存余量,再执行swapoff,最后顺手调优防复发。

3.1 第一步:检查内存与swap现状

先看整体水位:

free -h

看Swap行的used值。再看Mem行的available值——available才是内核认为“真正可以分配出去而不触发swap”的内存量,比free列里的数值更实用。如果available大于swap used的值,可以继续;如果相差不到10%,先去排查是哪个进程在吃内存:

ps aux --sort=-%mem | head -20

这一步极其重要。我见过太多人没看内存就直接swapoff -a,结果OOM Killer把数据库进程杀了,教训惨痛。

3.2 第二步:执行swapoff之前先锁定大内存进程

如果你在生产环境操作,我建议多做一步:查一下当前所有进程的swap占用情况,确认没有哪个进程异常占用了大量swap。Linux没有直接的“查看进程swap占用”命令,但可以通过两个途径间接判断:

一是检查/proc下的smaps文件:

grep VmSwap /proc/*/status 2>/dev/null | sort -k2 -n -r | head -10

二是用smem工具,如果系统里没有,先安装:

# Debian/Ubuntu apt install smem # RHEL/CentOS yum install smem smem -rs swap | head -20

这个工具看Swap列很直观。如果发现某个进程独占了几百MB甚至上GB的swap,而且它本身就是那个“高峰流量进程”,那就好办了——等它自然释放即可;如果它一直在长驻且swap占用线性上涨,说明可能存在内存泄漏,先处理泄漏再清swap才有意义。

3.3 第三步:执行swapoff再swapon

确认内存余量充足、没有异常进程后,直接执行:

sudo swapoff -a sudo swapon -a

这两条命令如果成功,free -h里的Swap used应该归零或者接近归零。为什么接近归零?因为swapon -a挂载后,内核会按当前工作负载重新建立一小部分交换页,这属于正常现象。

如果你只想释放某一个swap设备,不碰其他的,可以指定路径:

sudo swapoff /dev/sda2 sudo swapon /dev/sda2

如果是swap文件:

sudo swapoff /swapfile sudo swapon /swapfile

这里有个细节:swapon -a会按/etc/fstab配置自动挂载所有标记为swap的设备,而手动指定路径则只处理单个设备。日常单机操作直接用-a更省事。

3.4 第四步:验证释放结果

free -h swapon --show

swap used如果还剩一小部分,可以再等几秒重新看。内核换页是异步的,可能刚执行完显示还有残留,过一会儿就归零了。另外也可以用vmstat 1 3连续采样3秒看si和so两列的值——也就是swap in / swap out的每秒页数。如果释放后这两列数值都非常低,说明系统没有在持续疯狂换页,状态是健康的。

4. 三种swap类型下的不同“释放”姿势

上面说的流程,针对的是最标准的交换分区和交换文件。实际生产里还有几种变体,处理方式不同,我分别说一下。

4.1 swap分区与swap文件:统一采用上节流程

这两种在释放方式上完全一致,区别只在于持久化配置。分区型swap通常写在/etc/fstab里,格式大概是:

/dev/sda2 none swap sw 0 0

文件型swap则在挂载时指定了loop设备:

/swapfile none swap sw 0 0

如果你执行swapoff -a后不执行swapon -a,重启后会重新挂载,但当前登录会话里系统就没有swap了。所以在释放时我习惯成对执行,不要只执行一半。

这里还要多提醒一句:如果你之前用mkswap格式化过某个设备,但后来没写入/etc/fstab,那swapon -a不会重新挂载它。需要手动swapon。否则你执行的swapoff会让该设备保持未挂载状态,直到你手动挂载或重启。

4.2 ZRAM设备:不建议用常规swapoff

ZRAM的原理是用CPU压缩内存页面,再放入一块内存区域作为swap设备。它不涉及磁盘I/O,所以“占用swap空间”实际上是“占用了内存中的压缩块”。ZRAM的特点是:压缩率高的场景下,系统能“凭空”获得几倍的可用内存;但在你看到swapon --show时,它显示的是未压缩的逻辑大小,不是真实的物理内存占用。

对于ZRAM,如果你执行swapoff /dev/zram0再swapon /dev/zram0,确实能让它的used归零,但这会导致一个副作用:原本放在ZRAM里的压缩页被解压回RAM,内存的压力会瞬间增大,然后内核再决定是否重新压缩写入。这个过程又慢又消耗CPU,多数情况下得不偿失。

所以我的看法是:ZRAM场景下根本不追求used归零。如果ZRAM使用率过高,你应该关注的是总内存水位,而不是swap的used列。真要想重置ZRAM,在桌面Linux上可以通过重启服务或重启系统来完成,服务器场景我一般不推荐杀死进程强清。

4.3 swap文件新增或扩容的正确姿势

顺带讲一个相关但不同的话题——很多人发现自己swap不够用后,第一反应是释放,但我建议分情况处理。如果swap used长期超过50%,且服务对内存不敏感,直接新增或扩容swap文件可能更合理:

# 创建1G的swap文件 sudo fallocate -l 1G /swapfile_extra sudo chmod 600 /swapfile_extra sudo mkswap /swapfile_extra sudo swapon /swapfile_extra

注意fallocate在某些文件系统(如旧版XFS)上可能会产生空洞,而swap文件不允许有空洞。稳妥做法是用dd:

sudo dd if=/dev/zero of=/swapfile_extra bs=1M count=1024 sudo chmod 600 /swapfile_extra sudo mkswap /swapfile_extra sudo swapon /swapfile_extra

这两种方式产生的swap文件功能一样,但dd在兼容性上更保险。用dd创建1GB文件需要等待几十秒到几分钟,取决于磁盘速度,别把它当成故障。

5. 彻底“根治”:让swap不再轻易占满的调优思路

前面说过,释放swap只是治标。如果你频繁需要清理swap,说明系统存在“病根”。经过多次实践,我给读者建议的排查顺序通常是:

5.1 调整swappiness参数

先看当前值:

cat /proc/sys/vm/swappiness

大多数服务器默认是60,这个数值意味着内核在内存接近满的时候会“比较积极”地换出页面。如果物理内存够用,可以调低到10甚至0,让内核更倾向于保留物理内存页。临时设置:

sudo sysctl vm.swappiness=10

永久生效,写入/etc/sysctl.conf或/etc/sysctl.d/99-swap.conf:

vm.swappiness=10

然后执行:

sudo sysctl -p

注意,swappiness=0并不意味着禁用swap,它只表示内核在无强压力下不去换出匿名页。真正的swap禁用是把设备整个swapoff,这是两码事。

5.2 缩小swap min free的触发阈值

除了swappiness,还有一个参数容易被忽略:vm.min_free_kbytes。它表示内核在分配内存时保留的最小可用内存量。如果你的机器内存较大但系统会出现“明明内存没满,swap却开始被写”的现象,可以稍微调高这个值,让内存分配更早触发回收,减少swap的被动写入。

不过这个参数是双刃剑。调太高会增加内存回收和DMA失败的几率,一般不建议超过物理内存的1%以下。默认值通常由内核自动按内存大小设置,除非你明确知道问题所在,否则不要轻易动它。

5.3 定位占用swap最多的进程

结合上面的smem或/proc/*/status,找到占swap大头的进程。常见病根:

  • Java应用:JVM堆内存设置过大会导致大量堆页被换出,建议把-Xmx调小或调整GC策略,让堆对象尽量不进入swap。
  • 数据库:MySQL/PostgreSQL的buffer pool会占用大量内存,如果机器内存不足,建议显式调低innodb_buffer_pool_size或shared_buffers。
  • 文件缓存:页面缓存(page cache)在内存压力下也会被回收,但你不需要专门清理它,因为内核会自动处理;如果page cache占比过高且影响业务,可以适当调整vm.vfs_cache_pressure。

5.4 云服务器场景的特别提醒

云服务器上的swap往往位于云盘或本地盘上,I/O性能和物理内存差距悬殊。频繁换页(si/so数值过高)会导致应用卡顿,这时候与其“释放swap”,不如考虑:

  • 增加内存规格;
  • 重新设计进程的内存上限;
  • 使用更小的swap空间,比如从8GB缩到2GB,减少系统“无痛换页”的空间。

我个人在云主机上维护的一款后台服务,就是从“8GB swap + swappiness=60”调整为“2GB swap + swappiness=10”之后,swap used再也没持续超标过。

6. 实操中容易踩坑的细节补充

最后记录几个我在实际环境中踩过和见过的坑,希望能帮你避开。

6.1 swapoff报“Cannot allocate memory”

如果你执行swapoff -a时终端直接提示无法分配内存,说明物理内存余量不够承载swap里的全部数据。这时候不要硬来,赶紧按Ctrl+C中断,改用下面这种渐进方式:

# 先不同时关闭所有swap,而是逐个清理 # 同时减小swap替换压力 sudo sysctl vm.drop_caches=3 # 谨慎使用,会清空page cache

不过drop_caches只能释放文件缓存,无法直接释放匿名页。根本办法还是先杀掉吃内存的进程,或者等服务自然降峰后再操作。如果只是想降低swap used的数值,也可以考虑临时新增一块swap,等系统稳定后再清理旧的,思路类似“借道换乘”。

6.2 系统重启后swap问题复现

很多读者清完swap后发现重启后又满了。原因通常是:某个开机的服务一直在大量申请内存,直接吃满了RAM。此时你应该按第5节的方法排查进程,半途而废的“清swap”只会让你对系统状态误判。

6.3 容器环境下的swap陷阱

Docker默认允许容器使用宿主机的swap空间,所以在容器里跑Java服务,可能你们宿主机上看到swap used飙高,但容器里free看到的内存却很健康。排查时先确认你在哪一层看到的数据,再决定操作对象。docker stats可以看容器内存,宿主机上的swap状态还是得在宿主机上处理。如果你想让某个容器禁止使用swap,可以在docker run时加--memory-swap=0或设置--memory与--memory-swap相等来禁用swap扩展。

6.4 小心误删swap分区导致无法开机

操作不当可能导致系统重启后没有swap,但一般不影响开机。真正危险的操作是编辑/etc/fstab时写错了UUID或设备名,导致开机时swap挂载失败。所以如果你改了/etc/fstab,务必先执行:

sudo mount -a sudo swapon -a

确认无报错再重启。不要随手删除/etc/fstab里swap相关的行而不做验证。

7. 我的建议:以“预防”心态看待swap

总结这么多年跟Linux内存打交道的经验,我对swap的态度是:它是系统的一道安全缓冲,不是一块需要时刻保持“干净”的区域。释放swap本身并不难,难的是判断何时该释放、释放后如何防止它再次被无意义占满。

如果你只是想看一眼系统内存和swap状态:

free -h && swapon --show

如果swap used超标且物理内存余量充足,就按第3节的流程走一遍;如果回想一下流量峰值已经过去,但仍然频繁告警,就去查进程、调swappiness、审视容器配置。这套组合拳下来,你会有更清晰的认识。

我个人习惯是在每次大促或压测结束后做一次swap巡检,把free -h、smem、vmstat的输出存个快照,观察几个周期内的变化趋势,而不是一味追求“清零”。毕竟,Linux的内存管理远比表面看到的复杂,尊重内核的调度策略,比盲目干预有效得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 5:28:08

微信小程序树形组件封装实战:扁平化渲染与勾选联动实现

做后台管理系统的时候被树形选择的需求折腾过很多次,PC 端用 el-tree 几十行代码就能搞定的事情,挪到微信小程序里还真不是开箱即用。小程序的官方组件库里没有树形组件,也不支持直接嵌套递归渲染,每次都要自己封装一遍。这篇文章…

作者头像 李华
网站建设 2026/10/2 5:27:55

Stable Diffusion整合包实操指南:文生图、图生图与局部重绘全流程

做设计这行十几年,工具换了一茬又一茬,但Stable Diffusion这套AI绘图工具,确实是我碰到的第一套能让人一边干活一边出图的玩意儿。三个核心功能——文生图、图生图、局部重绘,刚好覆盖了从灵感草签到成稿精修的整条链路。这篇文章…

作者头像 李华
网站建设 2026/10/2 5:27:31

腾讯开源Octop:把AI工作台接入本地模型的中间层

直接在博文开头讨论腾讯开源的 Octop 项目,把它定位成连接 AI 工作台和本地模型的中间层。顺着“为什么要把工作台搬回本地”这条线展开,讲清楚架构、实操配置、模型选择、踩坑记录,最后再聊几句更进阶的玩法。整体尽量口语化,像同…

作者头像 李华
网站建设 2026/10/2 5:26:41

网页端接入海康摄像头:RTSP转HLS与WebRTC实战指南

搞网页端接入海康摄像头这件事,这两年找我咨询的人不少。很多人拿着新装好的摄像头,第一反应就是想把画面放到网页后台里实时预览,结果卡在第一步:浏览器打不开预览页,要么提示安装插件,要么黑屏转圈。老实…

作者头像 李华
网站建设 2026/10/2 5:25:56

AI工程从零开始:构建可验证、可回滚、可审计的生产级能力

1. 项目概述:从零构建AI工程能力,不是学框架,而是建地基“ai-engineering-from-scratch”这个标题乍看像一门课程名,但在我带过三十多个AI落地项目、亲手从零搭过七套生产级推理服务、重构过四家公司的模型交付流水线之后&#xf…

作者头像 李华
网站建设 2026/10/2 5:25:50

彩色、灰度、二值图像模式详解:转换原理、存储差异与工程实践

1. 三种图像模式,到底差在哪做图像处理这几年,我经常被问到“灰度图和黑白图不是一回事吗”“彩色图转灰度之后信息损失了多少”这类问题。不夸张地说,很多工作了三五年的开发者在做图片压缩、OCR预处理、模型训练数据准备时,依然…

作者头像 李华