我们先看一张框架图,有问题我们微信群(文章末尾有二维码欢迎扫码加入)或者评论去交流
在 Linux 内存模型中,Swap 不是一个“扩展内存”的工具,它应该是内核在内存压力(memory pressure)下的一种内存转换的机制吧。
核心问题是:当物理内存不足时,系统决定抛弃那个?
候选对象只有两类:
文件页(file-backed pages)
Page Cache
可直接丢弃(因为可以从磁盘重读)
匿名页(anonymous pages)
堆 / 栈 / malloc
必须写入 Swap 才能回收
这就是 Swap 存在的根本原因:给“不可丢弃”的匿名页一个“暂存区”
二、内存回收路径:从分配失败到 Swap 写入
当进程申请内存(如 malloc)时,路径大致如下:
alloc_pages() → get_free_pages() → try_to_free_pages() → shrink_node() → shrink_lruvec() → shrink_list()
核心发生在:
1. LRU 链表扫描(页淘汰核心机制)
Linux 使用多队列 LRU:
active / inactive
anon / file
即:
LRU_ACTIVE_ANONLRU_INACTIVE_ANONLRU_ACTIVE_FILELRU_INACTIVE_FILE
回收优先级:inactive → active(衰减后进入 inactive)
2. reclaim 决策分支
在 shrink_page_list() 中:
情况 A:文件页
干净页 → 直接释放
脏页 → writeback → 再释放
情况 B:匿名页
三、Swap 写入机制:从匿名页到磁盘
1. swap out 关键路径
try_to_unmap() → swap_out() → add_to_swap_cache() → swap_writepage()
关键:
此时:该页“不在内存中”,但“逻辑仍存在”
2. swap cache 的作用
Swap cache 是一个中间层:
避免重复写入
支持共享 swap entry(fork 场景)
四、Swap in:缺页异常驱动的数据回流
当进程再次访问被 swap 掉的页:
触发:page fault → do_swap_page() → swap_readpage()
主要流程有下面4个步骤:
从 swap 设备读取
分配新页框
更新页表(PTE present)
恢复执行
ta的本质:swap 把“内存不足问题”转化为“IO 延迟问题”
五、系统为什么会有时候会出现“卡死”现象
主要是没有合理使用Swap。
当工作集 > 内存容量且频繁 swap in/out就会出现抖动
系统进入:IO-bound 状态(CPU 在等磁盘)
主要表现有如下几种情况:
如果你是搞优化系统,应该很常见这几种情况
2. 关键影响因素:swappiness
vm.swappiness = 0 ~ 100
高 → 更倾向 swap anon
低 → 更倾向回收 page cache
控制“匿名页 vs 文件页”的牺牲优先级
(2)磁盘性能
HDD → 灾难
SSD → 可接受
NVMe → 相对可控
(3)内存访问局部性
局部性强 → swap 影响小
随机访问 → 性能崩溃
六、OOM vs Swap:在硬件设备上如果你做系统优化会遇到这个情况
当 reclaim 直接回收失败的时候有没有swap现象是不同的:
1. 有 Swap
2. 无 Swap
区别对比:
七、那么什么时候应该开 Swap呢
推荐开启的情况:
通用服务器(避免突发 OOM)
开发机 / 笔记本
内存波动大的业务
谨慎使用:因为这情况一旦设备异常就会丢失书籍
低延迟系统(交易、实时系统)
高性能数据库(Redis / HFT)
实际设备中建议:
设置较低 swappiness(10~20)
使用 SSD / NVMe
监控指标:
pgscan
pgsteal
pswpin / pswpout
我建了一个嵌入式Linux技术群,专门聊难题分析和求职面试,欢迎大家一起加入,共同解决工作中的疑难杂症问题