内存与 OOM58 条

KSM 同页合并

Kernel Samepage Merging 扫描并合并内容相同的页,节省内存(虚拟化场景常见),代价是 CPU 扫描开销。

什么是 KSM

KSM(Kernel Samepage Merging)是内核的去重机制:后台扫描进程地址空间中标记为 MERGEABLE 的匿名页,把内容完全相同的页合并成一份只读副本,写时再复制回来。它最典型的收益场景是一台宿主机跑多个相同镜像的虚拟机或容器,可以把内核镜像、相同代码段这类重复页大幅压缩。代价是扫描本身消耗 CPU,且合并后的页在被写入时需要额外复制。

基本信息

运行开关/sys/kernel/mm/ksm/run(1 开启,0 停止)
扫描强度pages_to_scan、sleep_millisecs
统计口径pages_shared(合并后页数)、pages_sharing(被省下的映射数)
合并对象仅 madvise(MADV_MERGEABLE) 标记的页和启用 KSM 的匿名页
CPU 开销扫描线程 ksmd 持续占用,强度越大越明显

典型使用场景

  • 虚拟化宿主:同镜像多虚拟机运行时分摊重复内存,提高超卖比
  • 容器密度优化:大量同构容器把基础镜像的只读页合并
  • 内存吃紧时的应急手段:临时开启扫描,缓解而不是根治
  • 评估去重收益:读 pages_sharing × 页大小估算节省量
  • 配合监控观察 ksmd 的 CPU 占用与合并页数趋势

查看与开关

查看与开关
cat /sys/kernel/mm/ksm/run                    # 1 表示正在运行
cat /sys/kernel/mm/ksm/pages_shared           # 已合并出的共享页数
cat /sys/kernel/mm/ksm/pages_sharing          # 共享映射数,乘页大小约等于节省量
cat /sys/kernel/mm/ksm/pages_to_scan          # 每轮扫描页数
echo 1 | sudo tee /sys/kernel/mm/ksm/run      # 临时开启
top -b -n1 | grep ksmd                        # 观察扫描线程 CPU 占用

指标判读

指标正常表现异常表现
pages_sharing/pages_shared比值明显大于 1 才说明有节省≈1 表示几乎没合并成功
run0 或 1 稳定反复切换说明有脚本在干扰
ksmd CPU低个位数百分比持续高占用说明扫描强度过大
pages_volatile 升高页被修改导致取消合并写密集负载下合并收益接近零
页大小按 4KiB 估算节省量即可:pages_sharing × 4KiB 是粗算值,实际节省还要扣除共享页本身的开销。
多租户或强隔离要求的环境要谨慎:页合并意味着不同租户的内存物理上共享,存在侧信道与合规层面的顾虑。
别把 KSM 与透明大页(THP)混为一谈:THP 优化的是页表与 TLB 开销,KSM 做的是内容去重,两者机制独立、可以同时存在,排查内存问题时分别核对。

易错点

  • 合并后写时复制放开,写密集负载省不了多少内存还要多付 CPU,先做收益评估再启用
  • 多租户场景评估侧信道影响与合规要求后再启用,安全等级高的环境通常直接禁用
  • 只看 pages_shared 不看 pages_sharing 会误判收益,比值接近 1 时基本没有节省
  • 扫描参数调得过激进(pages_to_scan 大、sleep_millisecs 小)会让 ksmd 抢 CPU,影响业务进程

数据来源与参考

  • Linux 内核 Documentation/admin-guide/mm/ksm.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌