KSM
Overview
KSM(Kernel Same-page Merging)是 Linux 内核中的一个内存优化机制,主要用于在多个进程之间合并相同内容的内存页,从而减少物理内存的使用。
工作原理
- 扫描内存:KSM定期扫描内存中的页面。 
- 建立哈希表:对于相同的页面内容,KSM会在内部建立哈希表进行追踪。 
- 合并页面:一旦有两个或多个页面的内容相同,KSM会将它们合并为一个单独的共享页面。 
- 写时复制:如果共享页面中的一个进程需要对其内容进行更改,会触发写时复制机制,为该进程分配一个新的页面。 
优势
- 内存节省:通过只存储一个副本,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_profit和- process_profit指标;支持按进程启用 KSM。
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