在 Linux 里,一旦建立了虚拟内存到匿名页的页表映射,那么进程就可以访问这块匿名内存。由于系统长时间的运行,系统可用物理内存在不断变少,为此系统会进行内存回收(Memory Reclaim), 前面开发者已经了解了 SWAP 方案,那么该方案存在一个缺点就是磁盘 IO 特别多,因为需要把匿名页 SWAP-OUT/SWAP-IN,因此这会增加缺页时的延迟. 为了兼顾方案提出了 ZSWAP 方案,即系统内存压力比较大时,将不常用的匿名页进行压缩,并将压缩后的数据存储物理内存上,以此释放匿名页。待进程再次访问匿名内存时,MMU 发现对应的物理页不存在,那么触发缺页异常,并在缺页异常处理函数中识别发生了内存压缩,因此将对应的内容进行解压到新的物理页上,接着更新页表到该物理页上,该物理页变成匿名页,接下来进程可以对匿名内存正常访问.
当一个匿名页被压缩之后,其对应的页表会记录匿名页在 ZSWAP 信息,缺页异常处理函数将 PTE Entry 非空,且 _PAGE_PRESENT 标志位清零,这类匿名内存归结为发生 SWAP OUT 操作(缺页异常无法识别是发生了 SWAP-OUT 还是内存压缩,统一当做 SWAP OUT 来处理). 此时页表的 [59: 63] 字段记录了 SWAP Type,这里不对 SWAP/ZSWAP 机制进行过多介绍,开发者只要了解 SWAP-PTE Entry 的布局即可,缺页异常处理函数可以从 SWAP Type 字段获得 ZSWAP 机制提供的信息,以便判断匿名页能否正确解压缩. 接下来是 [9: 58] 字段记录了匿名页被交换到 ZSWAP 区域索引的反码, 缺页异常处理函数可以从该字段知道匿名页在 ZSWAP 的具体位置. 其余字段这里不做过多介绍.