2026-04-27 · os
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。



























Swap 把匿名页(堆、栈、malloc 分配)搬到磁盘/压缩后端,腾出物理 RAM。“swap 是不是该关掉”是运维永恒争论。
flowchart LR
ANON[匿名页 inactive] --> REC[回收器]
REC -->|磁盘 swap| SDEV[swap 分区/文件<br/>/dev/sda2]
REC -->|zram| ZRAM[zram 设备<br/>内存压缩]
REC -->|zswap| ZSWAP[zswap 压缩池<br/>→ 满时泄到 swap]
SDEV --> SWAPIN[swap in<br/>major fault]
ZRAM --> SWAPIN
ZSWAP --> SWAPIN
SWAPIN --> ANON2[恢复匿名页]
classDef mem fill:#388bfd22,stroke:#388bfd,color:#adbac7;
classDef disk fill:#f0883e22,stroke:#f0883e,color:#adbac7;
classDef comp fill:#3fb95022,stroke:#3fb950,color:#adbac7;
class ANON,ANON2,REC mem
class SDEV disk
class ZRAM,ZSWAP comp
swapon --show
# NAME TYPE SIZE USED PRIO
# /dev/sda2 partition 8G 1.2G -2
# /swapfile file 4G 0B -3优先级高的先用。分区 swap 性能略好于文件 swap(少一层 VFS)。
页被换出后,PTE 里存的不是物理地址,而是 swap entry:
bit 0 = 0 (不 present)
bit 1..62 = swap type + offset
缺页时内核解析 entry → 找到 swap 位置 → 读回。
刚 swap-in 的页暂留 swap cache——如果马上又要换出,省一次写。page 同时有物理地址和 swap entry。
D-36 提过,再强调:
vm.swappiness = 60 → 扫 anon 和 file 的比例约 60:140
= 0 → 几乎只扫 file(除非没 file 可回收)
= 200 → anon 权重极高(配合 zram 有意义)
zram 创建一个内存中的块设备,数据压缩存储:
modprobe zram
echo lz4 > /sys/block/zram0/comp_algorithm
echo 4G > /sys/block/zram0/disksize
mkswap /dev/zram0
swapon -p 100 /dev/zram0压缩比通常 2-3x → 4GB zram ≈ 多出 8-12GB “虚拟 RAM”。
场景: - Android 标配(Chrome OS 也是) - 嵌入式、低内存 VPS - 桌面混合用(zram + 小 swapfile 做 fallback)
开销:压缩/解压 CPU;lz4 很快(几 μs/页),zstd 压得更紧但稍慢。
zswap 是 swap 的前端压缩池——页先压缩到内存池;池满才泄到真实 swap。
echo 1 > /sys/module/zswap/parameters/enabled
echo lz4 > /sys/module/zswap/parameters/compressor
echo 20 > /sys/module/zswap/parameters/max_pool_percent
echo zsmalloc > /sys/module/zswap/parameters/zpoolvs zram:
swap in 时预读相邻的 swap 页面:
page_cluster sysctl 控制(默认 3 → 2^3 = 8
页)。SSD 上设小(0-1),HDD 上保持默认。
memory.swap.max = 2G # 容器 swap 上限
memory.swap.current # 当前 swap 用量
memory.zswap.max = 1G # zswap 配额(6.5+)
kubelet 长期要求关 swap。1.28+ beta 支持
swap(NodeSwap feature gate)。
LimitedSwap:只允许 Burstable podUnlimitedSwap:所有 pod 可 swap生产建议:先在非关键节点测试。
数据库几乎都建议关 swap 或 swappiness=1。swap 带来的延迟不可预测——宁可 OOM 快速重启。
开的理由: - 给内存压力一个缓冲——OOM Killer 是最后手段 - 不常用的后台进程占页能被换出 - zram 几乎零成本
关的理由: - 数据库、实时系统不能容忍 swap 延迟 - 大内存服务器(512GB+)swap 意义不大 - Kubernetes 历史上不支持
折中方案: - zram + swappiness=100(Android/ChromeOS 风格) - 小 swap + vm.swappiness=1(服务器风格)
free -h # Swap 行
vmstat 1 # si/so 列
sar -W 1 # pswpin/s pswpout/s
cat /proc/meminfo | grep -i swap
# 哪个进程在 swap
awk '/VmSwap/{if($2>0)print FILENAME,$0}' /proc/*/status 2>/dev/null | sort -k3 -rn | head
# swap I/O 延迟
bpftrace -e 'kprobe:swap_readpage { @start[tid]=nsecs; }
kretprobe:swap_readpage /@start[tid]/ { @us=hist((nsecs-@start[tid])/1000); delete(@start[tid]); }'Documentation/admin-guide/mm/zswap.rst、Documentation/admin-guide/blockdev/zram.rstmm/swap_state.c、mm/zswap.c、drivers/block/zram/swapon --show、free -hvmstat、sar -Wzramctl/proc/meminfo、/sys/block/zram0/bpftrace swap tracing上一篇:内存回收 下一篇:OOM Killer
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-04-27 · os
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
2026-05-03 · os
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。
2026-05-07 · os
glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。
2026-05-18 · os
io_uring 用共享内存 ring buffer 实现零 syscall 异步 I/O——SQ/CQ、SQPOLL、IOPOLL、注册 fd/buffer、multishot、安全模型演化。本文深入内核实现与工程实践。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。