在 Linux 系统中, swap(交换空间)
是虚拟内存的一部分,作用是在物理内存(RAM)不足时,将部分不活跃的内存页移到磁盘上的 swap 分区或 swap 文件中,从而为活跃进程腾出内存空间。
一、为什么会使用 swap?
swap 的设计初衷 是提高系统的内存容错性和进程调度灵活性。
原因分析:
原因 | 说明 | 场景 |
---|---|---|
RAM 不足 | 系统物理内存不够用,必须换页到磁盘 | 同时运行多个大内存应用,如数据库 + 浏览器 + 编译器 |
页面置换算法 | 内核会根据“最不常用(LRU)”策略,将长时间未使用的页移到 swap | 很久未操作的后台服务内存页可能被 swap 出 |
应用程序内存泄漏 | 应用持续申请内存但未释放,内存被耗尽 | Java 应用内存泄漏导致大量 swap |
瞬时内存高峰 | 短时间内内存占用暴增时,swap 被动启用 | 解压大压缩包或批量操作大文件时瞬时爆内存 |
文件缓存压力 | 文件 I/O 造成 page cache 占用过多,挤压了匿名内存空间 | rsync、大量读写造成 page cache 膨胀 |
二、什么情况下会使用到 swap?
Linux 内核使用 swap 的决策与以下因素有关:
1. 可用内存不足
当可用内存(Available)接近 0,系统必须将部分内存页换出。
2. vm.swappiness
系统参数(0~100)
- 值越大,越积极使用 swap(默认是 60)。
- 值为 0,表示尽量不使用 swap,除非完全用完。
3. 进程优先级
- 内核会选择不活跃、长时间未访问的页优先换出。
三、如何监控系统是否使用 swap?
1:使用 free
命令
free -h
输出:
total used free shared buff/cache available
Mem: 7.5G 6.2G 0.5G 1.1G 0.8G 0.9G
Swap: 2.0G 1.3G 0.7G
Swap used
非零代表正在使用 swap。
2:使用 vmstat
vmstat 1 5
输出:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 108572 150540 515952 0 0 0 1 0 0 1 0 99 0 0
0 0 0 108572 150540 515956 0 0 0 0 1152 2136 1 0 98 0 0
0 0 0 108572 150540 515956 0 0 0 0 1122 2132 1 1 99 0 0
0 0 0 108572 150540 515956 0 0 0 0 1118 2144 1 0 99 0 0
0 0 0 108572 150540 515956 0 0 0 0 1152 2156 1 1 99 0 0
si
(swap in):从 swap 读入的速率(KB/s)so
(swap out):写入 swap 的速率(KB/s)
当 si
或 so
持续为正值,代表系统正在使用 swap。
3:监控脚本
#!/bin/bash
# 文件名: monitor_swap_usage.sh
# 功能: 监控 swap 使用情况并生成日志
LOG_FILE="/var/log/swap_monitor.log"
THRESHOLD_MB=500 # 如果 swap 使用超过 500MB 则报警
# 获取当前 swap 使用情况(MB)
SWAP_USED_MB=$(free -m | awk '/Swap:/ {print $3}')
# 时间戳
NOW=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$SWAP_USED_MB" -gt "$THRESHOLD_MB" ]; then
echo "$NOW [警告] Swap 使用过高:${SWAP_USED_MB}MB" >> "$LOG_FILE"
else
echo "$NOW [正常] Swap 使用:${SWAP_USED_MB}MB" >> "$LOG_FILE"
fi
可通过 crontab
每分钟运行一次:
* * * * * /bin/bash /path/to/monitor_swap_usage.sh
四、如何避免使用 swap?
1:增加物理内存
- 根本解决方案,适用于高负载应用。
2:调整 vm.swappiness
# 查看当前值
cat /proc/sys/vm/swappiness
# 临时设置 swappiness 值为 10
sysctl -w vm.swappiness=10
# 永久修改(写入配置)
echo "vm.swappiness=10" >> /etc/sysctl.conf
建议:
- 0:尽量不使用 swap
- 10~20:适用于大内存服务器
3:优化内存使用
-
释放缓存:
sync; echo 3 > /proc/sys/vm/drop_caches
-
优化程序逻辑、避免内存泄漏
4:关闭 swap
# 关闭 swap(临时)
swapoff -a
# 永久关闭(注释 /etc/fstab 中的 swap 分区)
# 然后 reboot
生产环境慎用,可能导致 OOM 杀死进程。
swap 被使用的真实情景
Java 应用启动多个大内存实例
java -Xmx3G -jar app1.jar &
java -Xmx3G -jar app2.jar &
如果系统总内存 8GB,启动后,剩余物理内存仅 1~2GB,swap 开始使用。
监控输出:
free -m
total used free shared buff/cache available
Mem: 7.5G 6.2G 0.5G 1.1G 0.8G 0.9G
Swap: 2.0G 1.3G 0.7G