Linux Swap 使用暴增?一文搞懂排查思路与系统调优技巧

Linux Swap 使用暴增?一文搞懂排查思路与系统调优技巧

你有没有被这种现象吓到过?
明明服务器内存还有空间,Swap 区却突然飙升,甚至高得离谱,系统也开始卡顿、延迟上升、负载飙高。你一头雾水:这是内存不够用了?还是配置出了锅?Swap 怎么突然就“起飞”了?

别急着加内存,有时候,Swap 的暴涨是个“信号弹”,告诉你系统里有某个角落正在偷偷“消耗资源”,只是你没注意到而已。

今天我们就来彻底拆解这个问题,从 Linux Swap 的机制、异常排查到实战调优,带你逐步“揪出幕后黑手”。


🧠 Swap 是什么?它为什么会自动工作?

简单点说,Swap 是内存的“备用仓库”,当你的物理内存(RAM)快用满时,系统会把一些暂时用不上的内容(比如长时间未访问的程序数据)转存到硬盘上的 Swap 分区或文件中。

就像你房间里东西太多,会临时放进柜子里的箱子,虽然不是很方便,但总比堆在地上强。

Swap 的优点:

  • 系统不会因为内存瞬间用光而 OOM(out of memory)
  • 某些不活跃的后台服务不会占用宝贵的物理内存

但问题来了:
Swap 是硬盘啊,哪怕是 SSD,它的速度也远远比不上内存。一旦大量数据交换发生,系统就会“卡”,而且是那种你一眼看不出问题的卡顿


📈 Swap 使用飙升的常见误区

很多人一看到 Swap 用量高,就以为是内存不够。其实根本不是这回事。

我们先来看看几个典型误解场景:

❌ 误解 1:Swap 用了,就是内存不够

👉 错。系统默认配置下,即使物理内存够用,也可能提前触发 swap,尤其是当 vm.swappiness 设置得较高时(默认是 60)。

❌ 误解 2:Swap 用完了系统才会卡

👉 其实不然。一旦开始频繁 swap in/out,系统响应就可能变慢,因为硬盘 IO 占用上升,进程切换成本高。

❌ 误解 3:Swap 是坏东西,应该禁用

👉 不建议。禁用 Swap 会让系统一旦内存打满就直接杀进程,对生产环境来说风险更高。


🔎 Swap 暴涨的排查路径:一步步揪出“谁干的”

✅ 第一步:查看 Swap 使用情况

bash
free -h

重点看:

  • Swap 区的 Used 字段是否异常;
  • available 内存是否真的不足;

再结合 top / htop

bash
top -o %MEM

查找哪些进程占用了最多的内存,有可能是这些进程被部分 swap 掉。

✅ 第二步:追踪内存页的换出情况

使用 vmstat

bash
vmstat 1 5

重点关注 si(swap in) 和 so(swap out) 列:

  • 如果持续有 swap out 行为(so 不为 0),说明系统正在频繁使用 swap。
  • 如果 swap in 不断增长,说明系统不断从 swap 读数据回来,响应能力可能受到影响。

✅ 第三步:使用 smem 看每个进程的 swap 用量

bash
smem -rs swap

这个工具可以显示每个进程实际使用的 swap 量,快速锁定是哪个服务在搞鬼。

✅ 第四步:对比 swappiness 与内存占用状态

bash
cat /proc/sys/vm/swappiness

默认是 60,表示“当内存使用率超过 40% 时可能开始使用 swap”。

对于内存较多、对性能敏感的系统,推荐设成 10–20,降低 swap 使用倾向。


🛠 Swap 使用过高的常见元凶

📌 1. 某个进程内存泄露

典型表现是:单个进程的内存占用持续上涨,但系统没触发 OOM,只能悄悄往 swap 倒。

举例:某业务用了 Python 的某个缓存库,代码没加释放逻辑,导致后台线程越跑越占内存,几天后被系统慢慢 swap 出,响应变慢。

📌 2. 后台服务“闲而不死”,常驻后台

很多 cron、老旧服务(如 rsyncd、unused sshd)长期挂在后台,基本不用但系统又不敢杀,结果被 swap 掉后再次使用时拉回来很慢,造成延迟。

📌 3. JVM 程序配置不当

Java 服务默认会尽量吃掉物理内存(-Xmx),但当系统内存紧张时,内核优先把 JVM 的一些堆数据 swap 掉,导致 GC 时卡顿严重。

如果你发现 swap 用量高、且 Java 响应慢、GC 次数增加,这大概率就是锅。

📌 4. 系统缓存缓存太积极

系统的 page cache(用于文件系统缓存)可能会占据很大一块内存,从而挤压用户进程的空间,进而触发 swap 行为。

你可以通过 drop_caches 来清理试试看:

bash
sync; echo 3 > /proc/sys/vm/drop_caches

⚙️ Swap 调优策略全盘托出

🔧 1. 降低 swappiness 值

bash
echo 10 > /proc/sys/vm/swappiness

或者写进配置文件:

bash
echo "vm.swappiness = 10" >> /etc/sysctl.conf
sysctl -p

这可以让系统更偏向使用 RAM,而不是 swap。

🔧 2. 调整优先级使用 swapiness + swapfile 组合策略

创建一个优先级低的 swapfile,让系统“不得不用”时再用它:

bash
fallocate -l 4G /swapfile2
chmod 600 /swapfile2
mkswap /swapfile2
swapon -p 5 /swapfile2

🔧 3. 对大内存服务做隔离 & 限额

cgroups 或 Docker resource limits:

bash
docker run --memory="2g" --memory-swap="3g" ...

这样服务本身 swap 行为会受到控制,不影响全局系统。

🔧 4. 监控 swap 行为 + 告警机制

别等业务出问题才发现 swap 爆了!

可以用 Prometheus + Node Exporter 监控指标:

  • node_memory_SwapUsed
  • node_memory_SwapFree

再加上告警规则:

yaml
alert: SwapUsageHigh
expr: (node_memory_SwapUsed / node_memory_SwapTotal) > 0.7

🧠 深度思考:为什么 Swap 会在“你最不希望它来”的时候冒出来?

其实,Swap 不等于“问题”,它是系统在“兜底”的动作。
真正的问题是——你是不是把“临时应急仓库”当成了“长期储存空间”?

系统用 swap 时通常是在:

  • 你没有配置资源限制
  • 你没做资源分组隔离
  • 你没监控内存异常波动
  • 你没有优化调度策略

一言以蔽之:你把一辆高铁塞进了拖拉机的车厢,然后问:为什么这么慢?


✅ 什么样的服务器才不怕 swap?

想要 swap 使用不怕人,系统得具备以下几个特征:

  1. 有足够多的 RAM,并监控使用趋势
  2. 业务服务配置了内存限制和优雅降级机制
  3. 定期清理无效进程和长期无响应任务
  4. swappiness 调得合理,不做死等
  5. 有完善的 swap 使用告警和页面缓存清理机制

做到这些,Swap 就不会是吓你的“鬼”,而是你默默守护稳定的“备胎”。

知识库

TCP 队头阻塞全面解析:高并发下隐藏的性能瓶颈与优化策略

2025-7-7 10:53:19

知识库

Shell 脚本实战指南:内网 ARP 洪泛监控与飞书/邮件自动告警

2025-7-7 11:33:40

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧