2. 内存去重原理:物理内存页的共享机制、写时复制(COW)技术、去重带来的收益与开销
内存去重的核心思想是:当多个进程(或虚拟机)在物理内存中存放了内容完全相同的页面时,操作系统只保留一份物理副本,并将所有虚拟地址映射到该物理页。这种“合并相同页”的操作,能够显著降低物理内存的占用,提高内存密度。
本章将深入剖析内存去重的三大支柱:物理页共享机制、写时复制(Copy-on-Write, COW)技术,以及去重带来的收益与开销。理解这三者,是掌握 KSM(Kernel Same-page Merging)等去重技术的基石。
2.1 物理内存页的共享机制
在传统的内存管理中,每个进程拥有独立的虚拟地址空间,并通过页表映射到不同的物理页框。即使两个进程加载了完全相同的代码或数据,物理内存中也会存在两份冗余副本。内存去重打破了这种隔离,引入了共享页的概念。
共享机制的核心流程如下:
- 识别相同页:系统通过比较页面的内容(通常使用哈希校验或逐字节比较),发现内容完全一致的物理页。
- 建立共享映射:选择一个物理页作为“合并页”,将其他进程的虚拟地址重新映射到该页,并释放冗余的物理页框。
- 标记只读:所有共享映射的页表项均被标记为只读。这是为了配合写时复制机制,防止一个进程的写入破坏其他进程的数据。
关键概念:共享页的生命周期始于“合并”,终于“写时复制”。在共享状态下,所有进程对该页的读操作完全正常,但任何写操作都会触发异常。
下图展示了两个进程共享同一物理页的映射关系:
2.2 写时复制(COW)技术
写时复制(Copy-on-Write)是内存去重能够安全运行的关键保障。当某个共享页被进程尝试写入时,系统不能直接修改共享页,而必须执行以下步骤:
- 捕获写异常:CPU 检测到页表项为只读,触发缺页异常(Page Fault),并将控制权交给内核的 COW 处理程序。
- 分配新页:内核从空闲内存中分配一个新的物理页框。
- 复制内容:将原共享页的内容复制到新分配的页框中。
- 更新映射:修改触发写入的进程的页表项,使其指向新页,并赋予读写权限。
- 减少引用:原共享页的引用计数减 1。如果引用计数降为 0,则释放该页。
性能提示:COW 将“复制”操作从页面分配时推迟到实际写入时。对于大量只读共享的场景(如代码段、只读数据),COW 避免了不必要的复制,极大地节省了内存和 CPU 开销。
下图展示了写时复制的完整流程:
2.3 去重带来的收益与开销
内存去重并非没有代价。在工程落地时,必须权衡其带来的收益与引入的开销。下表从多个维度进行了对比:
| 维度 | 收益 | 开销 |
|---|---|---|
| 内存利用率 | 显著降低物理内存占用,提高虚拟机/进程密度 | 需要额外的元数据(如哈希表、引用计数)管理共享页 |
| CPU 开销 | 读操作无额外开销,直接访问共享页 | 页面扫描、哈希计算、页表修改、COW 异常处理均消耗 CPU |
| 延迟影响 | 批量合并后,内存分配压力减小 | COW 写操作引入额外延迟(缺页异常 + 内存复制) |
| 可扩展性 | 适用于大规模虚拟化环境,节省成本 | 共享页链路过长时,查找和更新效率下降 |
| 安全性 | COW 保证数据隔离,防止进程间数据泄露 | 侧信道攻击(如 Rowhammer)可能利用共享页时序 |
工程避坑:在内存去重系统中,如果页面内容频繁变化(如大量写入密集型应用),COW 会频繁触发,导致 CPU 飙升和延迟抖动。此时去重带来的收益可能被开销抵消,甚至出现性能回退。建议对工作负载进行 profiling 后,再决定是否启用去重。
下图从系统资源的角度,直观展示了去重前后的状态变化:
2.4 收益与开销的量化指标
在实际工程中,通常使用以下指标来评估去重的效果:
- 去重率(Dedup Ratio):
1 - (合并后物理页数 / 合并前物理页数)。例如,100 页合并为 40 页,去重率为 60%。 - COW 触发率:单位时间内 COW 异常的次数。高触发率意味着大量写入冲突,应警惕性能下降。
- 扫描开销:KSM 等后台线程扫描内存页所消耗的 CPU 时间片。
- 内存节省量:释放的物理页框总数,通常以 MB 或 GB 为单位。
经验法则:在虚拟化桌面(VDI)场景中,去重率通常可达 40%~70%;在数据库或高频交易场景中,去重率可能低于 10%,且 COW 开销可能超过收益。建议在启用去重前,先进行小规模压测。