KSM

Overview

KSM(Kernel Same-page Merging)是 Linux 内核中的一个内存优化机制,主要用于在多个进程之间合并相同内容的内存页,从而减少物理内存的使用。

工作原理

  1. 扫描内存:KSM定期扫描内存中的页面。

  2. 建立哈希表:对于相同的页面内容,KSM会在内部建立哈希表进行追踪。

  3. 合并页面:一旦有两个或多个页面的内容相同,KSM会将它们合并为一个单独的共享页面。

  4. 写时复制:如果共享页面中的一个进程需要对其内容进行更改,会触发写时复制机制,为该进程分配一个新的页面。

优势

  • 内存节省:通过只存储一个副本,KSM有效减少内存冗余。

  • 性能提升:特别对于虚拟机环境,KSM可以显著提高内存的使用效率和系统性能。

历史演进

KSM 最初是为 KVM 虚拟化环境开发的(当时称为 Kernel Shared Memory),目的是通过共享虚拟机之间相同的数据页来节省物理内存。

它在 Linux 内核 2.6.32 版本中正式合入主线,发布时间为 2009 年 12 月 3 日

以下是近几年 KSM 的主要改进,摘自 devkernel.io 的版本变更记录

  • 6.12:移除 PageSwapCache。

  • 6.11:优化快速变化页的处理,避免浪费时间在稳定树搜索。

  • 6.10:开始向 folio 架构过渡,修复 ksm_zero_pages 和 ksm_pages_scanned 的统计问题。

  • 6.8:引入 KSM advisor,可动态调整 KSM 设置;增加 tracepoint 和 sysfs 接口。

  • 6.7:新增 pages_skipped 指标;引入 “smart scan” 模式,跳过之前未成功去重的页。

  • 6.6:在 /proc/<pid>/smaps 中加入 KSM 统计信息;支持 unsharing KSM-placed zero pages。

  • 6.4:新增 general_profitprocess_profit 指标;支持按进程启用 KSM。

建议类型(advice)
说明

MADV_NORMAL

默认行为,适度预读数据。适合一般访问模式。

MADV_RANDOM

随机访问,尽量少读数据,避免浪费资源。

MADV_SEQUENTIAL

顺序访问,多预读数据,访问后可快速释放。

MADV_WILLNEED

即将使用,提前加载内存页。

MADV_DONTNEED

不再使用,允许内核回收内存资源。

MADV_FREE

标记为“懒释放”,等内存紧张时再清理。

MADV_REMOVE

彻底释放内存及其后端存储。

MADV_DONTFORK

fork 时不复制这段内存,避免不必要的开销。

MADV_DOFORK

取消 DONTFORK,恢复复制行为。

MADV_WIPEONFORK

fork 后子进程看到的是清零的内存。

MADV_KEEPONFORK

取消 WIPEONFORK,保留原始内容。

MADV_HWPOISON

模拟硬件内存错误,触发错误处理流程。

MADV_SOFT_OFFLINE

尝试软下线内存页,避免后续使用。

MADV_MERGEABLE

建议 KSM 合并内容相同的内存页。

MADV_UNMERGEABLE

禁止 KSM 合并这段内存页。

MADV_HUGEPAGE

尝试使用透明大页(THP)优化性能。

MADV_NOHUGEPAGE

禁止使用透明大页。

MADV_COLLAPSE

立即将普通页合并为大页。

MADV_DONTDUMP

防止这段内存被包含在 core dump 中。

MADV_DODUMP

允许这段内存被包含在 core dump 中。

MADV_COLD

暂时不会用,标记为“冷页”,便于回收。

MADV_PAGEOUT

立即将这段内存页写回磁盘。

MADV_POPULATE_READ

预加载可读页表,触发读页错误以加载。

MADV_POPULATE_WRITE

预加载可写页表,触发写页错误以加载。

Last updated