☰
Linux服务器内存吃紧?手把手教你用swap文件给系统扩容
2026/10/21 4:05:11 网站建设 项目流程

最近我在给一台只有2G内存的Linux服务器排查问题时发现,进程频繁被杀,服务老是莫名其妙挂掉,free一看内存早就见底了,连个缓冲余地都没有。当时最省事、见效最快的解法就是给系统增加swap空间,也就是大家常说的“交换分区/交换文件”。折腾完这轮之后,我把Linux增加swap空间的方法完整走了一遍,从最基础的原理到具体的操作命令,再到几个非常隐蔽的坑,都整理在下面。如果你也遇到内存吃紧、OOM频繁、或者想给云服务器加点“虚拟内存”兜底,这篇应该能帮你少走不少弯路。

1. 为什么要增加swap:先搞清楚手头这台Linux到底缺什么

很多人一听说“加swap”就以为是在给机器“加内存条”,其实完全不是一回事。swap本质上是用磁盘空间模拟内存,内存不够用时,内核会把一部分暂时用不到的内存数据挪到磁盘上,腾出物理内存给正在活跃运行的程序。你可以把它理解成家里的“后备仓库”:卧室堆不下了,就先搬到仓库,等要用的时候再搬回来。虽然仓库搬进搬出比卧室慢得多,但至少不会因为卧室满了就直接把人拒之门外。

1.1 swap到底解决了什么问题

Linux内核有一个机制叫OOM Killer,当物理内存耗尽、系统实在挤不出可用页时,内核会按照一套打分逻辑挑一个进程“杀掉”来释放内存。对线上服务来说,这非常致命,可能你数据库查询稍微复杂一点,或者后台批量任务一跑,进程就被莫名其妙kill掉。增加swap后,系统在物理内存吃紧时可以先把不活跃的内存页换到磁盘,从而延迟甚至避免OOM Killer的触发。

但这里有个容易误会的点:swap并不是“加了就万事大吉”。它只是把内存压力往后推了推,真正的性能瓶颈还在磁盘I/O上。如果系统频繁在内存和swap之间换入换出,你会发现load average爬升、服务响应变慢,这时候该加物理内存还是要加物理内存,swap只能当应急手段。

1.2 哪些场景最需要增加swap

根据我实际遇到的情况,下面几类场景基本是“刚需”:

  • 云服务器内存本身很小,比如1G到4G的入门机型,跑个Java应用或者编译一次前端项目,内存峰值瞬间飙满。
  • 同一台机器上跑的进程比较多,每个进程单独看占用不大,但合在一起就容易触顶。
  • 有批量任务或定时任务,平时内存没问题,但任务一跑就“尖峰”明显,峰值内存远超常态。
  • 笔记本需要休眠到磁盘(suspend-to-disk),这个依赖一个不小于内存大小的swap空间。

也有不需要加的情况:如果你的服务器内存非常充裕,空闲内存常年稳定在高位,增加swap反而没有必要。尤其在一些容器环境里,swap可能会掩盖内存泄漏问题,让运维更难及时发现问题。这种场景下建议谨慎使用swap,优先把监控和告警做好。

1.3 增加swap前先算一笔账

动手之前,先看下这台机器现在的情况。建议依次执行:

free -h swapon --show df -h

free -h能看当前物理内存和swap的已用/可用量,swapon --show能看到已有的swap设备和对应大小,df -h则是确认磁盘剩余空间,防止创建swap文件时把根分区塞满。

以我处理的那台2G内存服务器为例,创建swap文件前,free显示Swap行全是0,说明系统完全没有swap兜底。结合这台机器跑着一个中等规模的数据分析脚本,我把swap目标定在4G,和物理内存比例为2比1。这里没有绝对标准,通常建议物理内存2G以下时swap给2倍内存,2G到4G给1.5倍左右,4G以上给一半或按需设定。不过这只是经验值,实际按应用模型来更靠谱。

2. 两种主流方案:swap分区与swap文件该如何选

Linux下加swap的空间来源无非两种:一种是用独立的磁盘分区做swap,叫swap分区;另一种是在已有文件系统上创建一个大文件当swap用,叫swap文件。两种方式都可行,但适用的场景差别很大。

2.1 swap分区:传统方案的优势和限制

swap分区是传统服务器上最常见的做法,安装系统时直接划一块独立分区,或者后期用分区工具从空余磁盘空间里切出一块,然后执行mkswap格式化成swap格式,再swapon启用。

它的好处是性能相对稳定,不经过文件系统层,由内核直接管理块设备。坏处也很明显:调整大小非常麻烦。如果后期内存需求增加,你没法直接“扩容分区”,得先腾出相邻空间,或用LVM逻辑卷才能在线扩展。在云服务器上尤其尴尬,很多云平台的控制台根本不给你做物理分区二次划分的选项。

2.2 swap文件:灵活补丁,适合大多数场景

swap文件就是在某个已有的挂载目录(比如根目录/)下创建一个指定大小的文件,通过mkswap把它格式化成swap格式,再交给内核启用。

它的优势非常突出:创建、删除、调整大小都极其方便。想要4G就创建4G的文件,想改成8G就swapoff后换一个文件重来。不涉及重新分区,不破坏原有数据布局,对云服务器和日常折腾的Linux环境都非常友好。

唯一的性能疑虑是,swap文件经过文件系统层,单次读写可能比裸分区多一点开销。但在现代内核和SSD环境下,这个差距几乎可以忽略,实际瓶颈通常还是磁盘本身的I/O速度。

2.3 我为什么在云服务器上选swap文件

如果你问我个人习惯,我几乎无脑选swap文件,尤其针对云服务器。原因很简单,某朵云上的服务器包了一块系统盘,里面已经分了根分区,如果我再想去“挤”出一个swap分区,要么动分区布局,要么得依赖LVM重排,风险和复杂度都上去了。而swap文件只需要在根分区下创建,存放路径、大小都随我调整,完全不影响系统本身的磁盘结构。

两种方案对比如下:

对比项swap分区swap文件
创建难度需要分区工具和空余磁盘空间一行命令创建文件即可
调整大小困难,分区不太好在线伸缩简单,删除重建即可
适用环境物理机、装机时规划好云服务器、已有系统后期补丁
性能略优,但不明显现代内核下差距很小
维护性长期固定,不易动灵活,方便反复调整

如果你是在物理机上装机,并且明确知道自己需要多大swap,用分区没什么问题。但如果你只是想先解燃眉之急,或者服务器已经装好系统不想折腾分区表,直接上swap文件是最清爽的路径。

3. 实操:用swap文件给Linux增加swap,从创建到开机自启

下面这段是全文最核心的部分,我直接按操作顺序来写,所有命令都以一台标准Linux服务器为例。不同发行版略有差异,但整体流程通用。

3.1 第一步:先检查现有配置和磁盘余量

一口气执行下面三条命令:

free -h swapon --show df -h

输出里重点看三处:Swap总量、已经生效的swap设备列表、根分区或目标目录的可用空间。我在某台服务器上遇到过明明是4G的swap文件,创建完了但swapon没生效,结果swapon --show里什么也没有,最后发现是创建文件所在文件系统不支持某些特性。所以第一步别省,多看一眼能避免后面一脸懵。

3.2 第二步:创建swap文件并启用

先选好路径和大小。我一般放在根目录,命名为swapfile,大小按前面的估算来。以4G为例:

sudo fallocate -l 4G /swapfile

如果系统提示fallocate不支持或不成功,退回最通用的dd命令:

sudo dd if=/dev/zero of=/swapfile bs=1M count=4096

bs=1M代表每次读写1MB,count=4096表示读写4096次,结果正好是4096MB也就是4G。dd这条命令在某些老旧文件系统上兼容性更好,就是创建大文件时耗时会长一些。

文件创建完,立刻设置权限:

sudo chmod 600 /swapfile

这一步需要养成习惯。swap文件里可能残留内存中的敏感数据,如果权限太开放,普通用户就能读,风险极高。chmod 600让swap文件只有root可读写,这是底线操作。

接下来格式化并启用:

sudo mkswap /swapfile sudo swapon /swapfile

mkswap会把swap文件初始化为swap格式,并写入一个UUID;swapon则是让内核正式启用它。启用后马上验证:

swapon --show free -h

正常情况下,swapon --show会列出/swapfile,free里Swap行也会显示总用量变成4G。

3.3 第三步:写入/etc/fstab实现开机自动挂载

这里是最容易被新手漏掉的一步,也是最关键的一步。不写进fstab的话,重启后swap文件不会自动生效,你前面等于白做。

用你习惯的编辑器打开/etc/fstab:

sudo vim /etc/fstab

在文件末尾加一行:

/swapfile none swap sw 0 0

四段含义依次是:设备路径(这里是swap文件路径)、挂载点(swap没有实际挂载点,用none)、文件系统类型(swap)、挂载选项(sw表示启用设备交换)、dump和fsck检查标志(都填0)。

改完fstab,建议先执行一次:

sudo mount -a

如果这条命令没有报错,说明fstab配置语法没问题。但mount -a并不会真正“挂载”swap,它只检查配置。想确认是否生效,重启后再看swapon --show即可。如果不方便重启,就用swapon --all重新加载一下。

注意:想加个保险,编辑fstab之前先备份一份:sudo cp /etc/fstab /etc/fstab.bak,防止手滑改错导致系统无法启动。

3.4 第四步:按需调整swappiness参数

Linux内核里有个参数叫vm.swappiness,控制系统使用swap的“积极程度”,取值0到100。默认一般是60,意思是内存使用率较高时,内核会比较积极地调用swap。

对服务器来说,60往往太激进。我个人习惯先临时调低测试:

sudo sysctl vm.swappiness=10

这条命令立即生效,但重启后会丢失。想永久生效,在/etc/sysctl.conf或/etc/sysctl.d/目录下新建一个配置文件,写入:

vm.swappiness=10

然后执行sysctl -p让它生效。云服务器上建议设置在10到30之间,兼顾内存释放和磁盘I/O压力。具体取值后面第4节单独聊。

4. 常见问题与调优细节:我从实际踩坑里总结的排查清单

光会跑命令还不够,真正考验经验的是swap文件创建后那些“看起来很奇怪”的问题。这节把我在实际环境里遇到的高频问题整理一遍,每一条都有真实的处理思路。

4.1 swappiness到底设置多少合适

关于swappiness取值,网上有很多互相矛盾的说法。早年大家喜欢设成0,希望系统“尽量不用swap”。后来内核社区逐渐意识到,把swappiness设成0在某些版本里会导致内核过早回收page cache,反而降低文件缓存命中率。现在更稳妥的做法是设成较小的非零值,比如10。这个值既能让系统在内存比较紧张时及时换出冷数据,又不会因为频繁换入换出把I/O拖垮。

如果你拿不准,可以先设成10跑几天,观察vmstat里的si(swap in)和so(swap out)两个指标。两个值都接近0,说明物理内存够用,swap基本是兜底;如果很大,说明内存压力确实大,单纯调低swappiness治标不治本。

4.2 swap文件放在系统盘还是数据盘

这个问题很容易想当然。某次我把swap文件放到了单独挂载的数据盘上,理由是“数据盘空间大,不占系统盘”。结果观察一段时间后,发现数据盘是普通机械盘,I/O能力远不如系统盘自带的SSD。内存压力一大,swap读写直接把整块数据盘的性能拖垮,进而影响了所有建立在上面业务数据访问。后来我把swap文件挪回系统盘,虽然空间紧张一点,但I/O响应快得多,整体更稳。

所以经验是:swap文件优先放在I/O性能最好的盘上,这块盘的空间够用即可。如果是普通机械盘,宁可缩小swap文件体积也别放上去凑数。如果真的没条件,尽量把swappiness压低,减少swap实际写入频率。

4.3 swap空间很大但系统还是很卡是怎么回事

有些时候你明明给系统加了8G甚至16G swap,free里也显示available空间一大堆,可系统还是卡成PPT。这时候不要在swap总容量上找原因,要去看是否真的有换入换出动作发生。

我用dstat或vmstat来分析系统I/O行为:

vmstat 1 10

重点看si、so两列。si和so持续高企,说明内核频繁把内存页换到磁盘、又从磁盘换回来,这种状态下CPU大量时间花在等待I/O上,系统自然卡顿。这种情况增加swap只是“续命”,没有治疗意义。该加物理内存就加物理内存,或者优化应用自身的内存占用。

4.4 常见问题速查表

现象可能原因解决办法
swapon提示“insecure permissions”swap文件权限太开放执行chmod 600 /swapfile后再swapon
swapon提示“invalid argument”文件所在文件系统不支持swap改用dd创建文件,或换到ext4/xfs分区
重启后swap不见了/etc/fstab未配置补上/swapfile none swap sw 0 0,执行mount -a验证
创建大量swap文件但系统仍OOMswap空间小或swap频繁换入换出先查实际内存压力,再决定扩容物理内存
swapoff时提示设备忙大量内存页驻留在swap,内存不足先释放内存,或临时增加物理内存后再swapoff
文件系统是btrfsbtrfs不支持常规swap文件重新考虑swap分区,或配置专门的子卷选项

4.5 创建swap文件时fallocate和dd该怎么选

我在文章前面提到了fallocate,它有创建文件快的优点,但有个细节需要注意:在部分文件系统或者某些内核版本上,fallocate创建的文件是稀疏文件,看起来容量很大,实际没有真正占用磁盘块。这类文件在某些情况下用mkswap会失败或者运行异常。

所以如果你在创建swap时用了fallocate,mkswap阶段报了奇怪错误,不要犹豫,直接用dd方式重建:

sudo rm -f /swapfile sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

虽然dd创建大文件要等一会儿,但它保证文件内容真正落盘,兼容性最稳。这是我多年折腾下来的习惯:追求稳妥时,永远选dd。

另外提一个安全细节:如果你的服务器对安全性要求较高,可以考虑把swap文件放到加密盘上,但加密会带来额外CPU和I/O开销,普通服务器完全没必要。只要把文件权限锁死,别让普通用户读到,风险就可控。

5. 增加swap之后还能做什么:一些更深一层的建议

swap加完之后,并不是说事情就结束了。我习惯性地再做几件事,方便后面出问题时能快速定位。

一是装好监控工具,比如用系统自带的sar或补充安装sysstat,定期记录内存和swap使用情况。这样过几天就能看到swap是不是真的被频繁使用,来判断物理内存瓶颈到底存不存在。二是把核心服务的启动方式调整一下,如果是Java应用,显式设置-Xms和-Xmx;如果是容器编排,把内存request和limit配清楚。这些调整能减少应用对swap的无意识依赖,系统可以运行得更干净。

再就是监控swap空间剩余量,别让swap文件本身也满了。当swap使用率接近100%时,意味着系统已经压力巨大,这时候再去检查内存泄漏、扩展物理内存或者优化应用,才是真正的解决路径。

我个人的习惯是,把swap当作“安全气囊”,不是“扩容手段”。它存在的意义是在内存突然被打满时给系统争取响应急救的时间,而不是让我们假装内存很大。真正生产环境的核心服务,物理内存该给够就给够,能用性能换空间的地方也尽量别压在最底层。

最后再分享一个小技巧给新手朋友:在把swap文件交给系统之前,可以用swapoff -a把当前所有swap先关掉,再swapon你新创建的那一份,这样能确保新的swap设置干净地覆盖旧的,不会出现多个swap文件叠加之后混乱的问题。等运行一段时间发现新的swap大小合适,再回头清理旧配置。

这套方法我已经在好几台服务器上验证过,无论是应急救火还是日常预防,都能稳稳起到作用。如果你手头正好有一台内存吃紧的Linux机器,就按上面的流程来吧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询