内存管理-77-kernel-internals系列-Memory专题-Caching & Reclaim-8-Swap
一、Swap 章节翻译
注: 翻译自 https://kernel-internals.org/mm/swap/
Swap 把内存延伸到磁盘
1. 什么是 Swap?
Swap 允许内核把不常用的页从 RAM 搬到磁盘,给活跃使用腾出内存。当这些页再次被需要时,再从 swap 读回来。
RAM 满了,需要更多内存:
┌─────────────────────────────────────────────┐
│ RAM: [Active] [Active] [Inactive] [Active] │
└─────────────────────────────────────────────┘
│ ▼(换出 swap out)
┌─────────────────────────────────────────────┐
│ RAM: [Active] [Active] [FREE] [Active] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ Swap: [Inactive page] │
└─────────────────────────────────────────────┘
之后,该页被访问:
│
▼(换入 swap in)
┌─────────────────────────────────────────────┐
│ RAM: [Active] [Page back] [X] [Active] │
└─────────────────────────────────────────────┘
2. Swap 类型
2.1 Swap 分区
专用的磁盘分区做 swap:
# Create swap partition (during install or with fdisk) mkswap /dev/sda2 swapon /dev/sda2 # View active swap swapon --show # NAME TYPE SIZE USED PRIO # /dev/sda2 partition 8G 1.2G -2
2.2 Swap 文件
普通文件做 swap:
# Create a 4GB swap file (works on ext4 and similar filesystems) fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile # Make permanent in /etc/fstab: # /swapfile none swap sw 0 0
注意: fallocate 在 ext4 上建 swap 文件很可靠。在 XFS 和某些其他文件系统上,可能产生内核无法用于 swap 的 extent;用 dd if=/dev/zero of=/swapfile bs=1M count=4096 是通用安全的替代。
btrfs(COW 文件系统)注意: 必须在文件有数据之前设置 +C(no-copy-on-write)属性(见 chattr(1)):
# Method 1: Create empty file, set +C, then allocate touch /swapfile chattr +C /swapfile fallocate -l 4G /swapfile chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile # Method 2: Set +C on parent directory (new files inherit it) mkdir /swap && chattr +C /swap fallocate -l 4G /swap/swapfile # ... then mkswap, swapon as usual
2.3 zswap(压缩 Swap 缓存)
写盘前先压缩,经常完全避免磁盘 I/O:
Page to swap out
│
v
Compress in RAM (zswap pool)
│
├── Fits in pool? ──► Store compressed (no disk I/O)
│
└── Pool full? ──► Write to backing swap device
zswap 相关操作:
# 启用 zswap echo 1 > /sys/module/zswap/parameters/enabled # 配置压缩器和池 echo lz4 > /sys/module/zswap/parameters/compressor echo 20 > /sys/module/zswap/parameters/max_pool_percent # 查看统计 grep -r . /sys/kernel/debug/zswap/ 2>/dev/null
2.4 zram(压缩 RAM 盘)
带压缩的基于 RAM 的块设备 —— 不用磁盘的 swap:
# 加载模块 modprobe zram # 设大小(压缩后有效容量更大) echo 4G > /sys/block/zram0/disksize # 做 swap 用 mkswap /dev/zram0 swapon /dev/zram0 -p 100 # 优先级高于磁盘 swap
3. Swap 架构
3.1 Swap Areas
Linux 支持多个带优先级的 swap areas:
# 查看 swap 区 cat /proc/swaps # Filename Type Size Used Priority # /dev/sda2 partition 8388604 1234560 -2 # /dev/zram0 partition 4194300 567890 100
高优先级先用,数值越大优先级越高。优先级相同的轮询(round-robin)条带化使用。
3.2 Swap Cache
刚换入的页会在 swap cache 里短暂保留:
Swap cache: ┌─────────────────────────────────────────┐ │ Page in RAM + still on swap │ │ (if process forks, child can share) │ └─────────────────────────────────────────┘
如果换入的页没被修改又被换出,无需写盘。
3.3 Swap Slot
Swap 空间按 slot 划分(一页一 slot):
/* Each slot tracks one swapped page */ swap_entry_t entry = swp_entry(type, offset); /* type: which swap area */ /* offset: slot within that area */
4. Swapping 机制
4.1 Swap Out(内存页到磁盘)
内存压力 │ ▼ 选要牺牲的页(从 inactive 链表) │ ▼ 分配 swap slot │ ▼ 页写到 swap │ ▼ 更新 PTE:present=0,swap_entry=slot │ ▼ 释放页框
4.2 Swap In(磁盘到内存页)
进程访问被换出的页 │ ▼ 缺页(not present) │ ▼ 从 PTE 读 swap entry │ ▼ 分配页框 │ ▼ 从 swap 读到页里 │ ▼ 更新 PTE:present=1,page_frame=new │ ▼ 进程继续
5. Configuration
5.1 Swappiness
控制偏向换出匿名页还是丢文件缓存:
cat /proc/sys/vm/swappiness
# 60 (default)
# Lower = prefer dropping cache, avoid swapping
echo 10 > /proc/sys/vm/swappiness
# Higher = more willing to swap
echo 80 > /proc/sys/vm/swappiness
# 0 = swap only to avoid OOM (not never)
5.2 Swap 优先级
# 启用时设优先级 swapon -p 100 /dev/zram0 # 高优先级 swapon -p -2 /dev/sda2 # 低优先级(默认) # 在 /etc/fstab 里: # /dev/zram0 none swap sw,pri=100 0 0 # /dev/sda2 none swap sw,pri=-2 0 0
5.3 Overcommit
# 内存 overcommit 策略
cat /proc/sys/vm/overcommit_memory
# 0 = 启发式(默认)- 允许合理的超分
# 1 = 总是允许 - malloc 永不失败
# 2 = 严格 - 限制为 swap + ratio*RAM
# 模式 2 的比例:
cat /proc/sys/vm/overcommit_ratio
# 50(默认)= swap + 50% RAM
6. 监控
6.1 Swap 用量
# free -h
total used free shared buffers
Mem: 18G 18G 258M 125M 11M
-/+ buffers/cache: 18G 269M
Swap: 10G 0 10G
# Detailed
cat /proc/meminfo | grep -i swap
# SwapCached: 123456 kB (pages in swap and RAM)
# SwapTotal: 8388604 kB
# SwapFree: 7000000 kB
6.2 Swap 活动
# 换入换出的页数 cat /proc/vmstat | grep -E "pswpin|pswpout" # pswpin - 从 swap 读入的页 # pswpout - 写到 swap 的页 # 实时监控 vmstat 1 # si = swap in(KB/s) # so = swap out(KB/s)
6.2 每进程 Swap
# 某进程的 swap 用量 cat /proc/<pid>/status | grep -i swap # VmSwap: 1234 kB # 全系统总量 -好像并不好用 awk '/VmSwap/{sum+=$2} END {print sum" kB"}' /proc/*/status 2>/dev/null # swap 大户排序 grep VmSwap /proc/*/status 2>/dev/null | sort -k2 -n | tail
6.3 zswap 统计
cat /sys/kernel/debug/zswap/pool_total_size # 压缩后大小 cat /sys/kernel/debug/zswap/stored_pages # zswap 中的页数 cat /sys/kernel/debug/zswap/written_back_pages # 被挤到磁盘的页
7. 演进(Evolution)
原始 Swap(v0.12,1992 年 1 月)
Linux 0.12(1992 年初)加入 Swap(虚拟内存量)。RELNOTES-0.12 描述了新的 mkswap 程序和 swap 激活。Linux 0.01 没有 swap。
多 Swap 区(v1.3)
支持多个带优先级的 swap 分区。
Swap 文件(v2.6)
Swap 文件与分区一样高效 —— 内核在 swapon 时把文件块映射到磁盘扇区,直接做块 I/O,完全绕过文件系统。
zswap(v3.11,2013)
提交:2b2811178e85("zswap: add to mm/")
压缩 swap 缓存以减少磁盘 I/O。
zram Swap(v3.14,2014)
提交:cd67e10ac699("zram: promote zram from staging")
zram 从 staging 进入主线,可做无盘 swap。
THP Swap(v4.13,2017)
提交:38d8b4e6bdc8("mm, THP, swap: delay splitting THP during swap out"),作者 Huang Ying
透明大页可不先拆分直接换出。
Swap-over-NFS(实验中)
允许换出到网络存储,给无盘系统用,仍在进行中。
8. Swap vs No Swap
8.1 支持 Swap 的理由
----------------------------------------------------------------------------------------------------------------------------- 好处 说明 ----------------------------------------------------------------------------------------------------------------------------- OOM 预防 OOM killer 之前多一层缓冲 休眠 suspend-to-disk 需要 swap 闲页驱逐 不用的页可以搬出去 Overcommit 安全 内存尖刺多点余量 -----------------------------------------------------------------------------------------------------------------------------
8.2 反对 Swap 的理由
----------------------------------------------------------------------------------------------------------------------------- 顾虑 说明 ----------------------------------------------------------------------------------------------------------------------------- 延迟 Swap 慢,可能卡死 SSD 磨损 频繁换出磨损闪存 抖动 重度 swap = 系统不可用 掩盖问题 掩盖内存泄漏 -----------------------------------------------------------------------------------------------------------------------------
8.3 Recommendation
大多数系统受益于少量 swap。内核本身不给 sizing 建议 —— 这是发行版层面的决策。常被引用的指南是 Red Hat RHEL 9 文档:
----------------------------------------------------------------------------------------------------------------------------- RAM Swap(无休眠) Swap(有休眠) ----------------------------------------------------------------------------------------------------------------------------- ≤ 2 GB 2x RAM 3x RAM 2-8 GB 等于 RAM 2x RAM 8-64 GB 至少 4 GB 1.5x RAM > 64 GB 至少 4 GB 不推荐 -----------------------------------------------------------------------------------------------------------------------------
叠加 zswap 可大幅减少磁盘 I/O。嵌入式系统因存储有限、工作负载可预测,常不用 swap。
9. 常见问题
9.1 Swap Thrashing(抖动)
不停换入换出,系统不可用。
症状:vmstat 里 si / so 很高,系统无响应
解法:加 RAM、减负载、调低 swappiness、杀内存大户
9.2 Swap Full(耗尽)
swap 空间没了。
症状:明明有“空闲”内存却 OOM kill
解法:加 swap、开 zswap/zram、查内存用量
9.3 SSD 磨损
过多 swap 写磨损 SSD。
解法:用 zswap(写减少 2-5 倍)、降低 swappiness、加 RAM.
注: zswap 应该是介于 RAM 和磁盘存储之间的一个东西,ZRAM不需要。
10. 参考
10.1 关键代码
----------------------------------------------------------------------------------------------------------------------------- 文件 说明 ----------------------------------------------------------------------------------------------------------------------------- mm/swapfile.c Swap 区管理 mm/swap_state.c Swap cache mm/zswap.c 压缩 swap 缓存 drivers/block/zram/ zram 实现 -----------------------------------------------------------------------------------------------------------------------------
10.2 Kernel Documentation、
Documentation/admin-guide/mm/zswap.rst
10.3 Related:
reclaim(何时触发 swap)、
page-cache(文件页 vs 匿名页)、
mmap(被换出的匿名内存)
11. 延伸阅读
mm/swap_state.c —— swap cache 实现:在 swap cache 中添加、查找和失效页面
mm/swapfile.c —— swap 区管理:swapon/swapoff、slot 分配、优先级处理和 swap map
Documentation/admin-guide/mm/concepts.rst —— 内核文档中关于匿名内存、swap 和回收概念的概述
《Toward a better swapping policy》(LWN,2015)—— 关于 swappiness、回收代价模型,以及内核如何在文件缓存与匿名页换出之间权衡的讨论
zswap —— 压缩 swap 缓存,在页面到达磁盘 swap 设备之前将其拦截
swap-thrashing —— 当工作集超过 RAM 时导致的活锁的检测与恢复
swapping —— 换入和换出的页级机制,包括 swap cache 生命周期
reclaim —— 内核在内存压力下如何选择牺牲页进行驱逐并触发换出
posted on 2026-10-09 10:26 Hello-World3 阅读(4) 评论(0) 收藏 举报
浙公网安备 33010602011771号