zswap 是 Linux 内核的一个特性,它充当一个压缩式交换缓存,它的核心思想是:当系统需要将内存中的匿名页(如进程的堆、栈、数据段)交换到磁盘上的交换分区/文件(swap)时,zswap 并不立即写入磁盘,而是先在内存中进行压缩,然后将压缩后的数据存储在一个内存池中。

只有当这个内存池满了,或者内存压力非常大时,zswap 才会将压缩后的数据写入磁盘的 swap 空间,这样做的好处是:
- 减少磁盘 I/O:磁盘 I/O 通常是系统性能的瓶颈。
zswap通过在内存中压缩,极大地减少了实际的磁盘交换操作,从而提升了系统的响应速度。 - 延长 SSD 寿命:对于使用 SSD 作为 swap 分区的系统,减少了写操作次数,有助于延长 SSD 的使用寿命。
如何启用和禁用 zswap
在修改参数之前,你需要知道如何控制 zswap 的开启和关闭。
内核编译时启用
如果你自己编译内核,需要在 .config 文件中启用以下选项:
CONFIG_ZSWAP=y
运行时动态控制(推荐)
对于大多数现代 Linux 发行版(如 Ubuntu 18.04+, CentOS 8+, RHEL 8+, Fedora 等),zswap 内核模块默认是编译进内核的,我们可以通过 /sys 文件系统在运行时动态控制。

检查 zswap 是否可用:
ls /sys/module/zswap/parameters/
如果能看到参数文件,说明 zswap 已加载。
启用 zswap:
# 设置 zswap.enabled=1 echo 1 | sudo tee /sys/module/zswap/parameters/enabled
禁用 zswap:

# 设置 zswap.enabled=0 echo 0 | sudo tee /sys/module/zswap/parameters/enabled
检查 zswap 状态:
cat /sys/module/zswap/parameters/enabled # 输出为 Y 表示已启用,N 表示已禁用
核心 zswap 参数详解
以下是 zswap 最常用和最重要的参数,都位于 /sys/module/zswap/parameters/ 目录下。
| 参数名 | 默认值 | 描述与调优建议 |
|---|---|---|
enabled |
N |
主开关。Y 代表启用,N 代表禁用,这是控制 zswap 功能的首要参数。 |
pool |
zbud |
压缩后页存储后端,定义了用于存储压缩后数据的内存池实现。 • zbud: 默认选择,它设计用于高压缩率场景,内存利用率高,但压缩性能一般。• z3fold: 另一个选择,内存利用率比 zbud 更高,但实现更复杂,可能在某些场景下有轻微性能开销,适合内存非常紧张的系统。• zsmalloc: 早期版本使用,已被 zbud 和 z3fold 取代,通常不建议使用。 |
max_pool_percent |
20 |
内存池最大占用比例。zswap 内存池最多能占用系统总内存的百分比,在 16GB 内存的系统上,最大池大小为 16 * 0.20 = 3.2GB。调优建议:根据你的内存大小和负载调整,如果内存充裕,可以适当调高(如 25%-30%),以存储更多压缩页,减少磁盘 I/O,如果内存紧张,则调低(如 10%-15%)。 |
compressor |
lzo |
压缩算法。zswap 支持多种压缩算法,这是一个关键的性能权衡点。• lzo: 默认选择,压缩和解压速度非常快,压缩率适中,是性能和压缩率的良好平衡点,适用于大多数场景。• lz4: 速度比 lzo 更快,但压缩率稍低,如果你的首要目标是极致的压缩/解压速度,可以选择它。• zstd (Zstandard): 压缩率非常高,尤其在较高压缩级别下,同时速度也很快,如果你有较多的 CPU 资源,并且希望节省更多内存,zstd 是一个极佳的选择。• deflate: 传统的 zlib 算法,压缩率高,但速度较慢,通常不推荐。调优建议: - 追求速度:选择 lz4。- 追求压缩率/内存节省:选择 zstd。- 通用/不确定:保持默认的 lzo。 |
same_filled_pages_enabled |
Y |
处理全同页面,当内存页的所有字节都相同时(一个新分配的堆页面通常被填充为 0),这些页面可以被更高效地表示,而不需要压缩,启用此选项可以显著提高这类页面的处理效率并节省池空间。 调优建议:保持启用 Y,因为这是一个优化特性,几乎没有坏处。 |
如何查看 zswap 的运行状态
了解 zswap 的工作情况对于调优至关重要,你可以通过 /sys/kernel/debug/zswap 目录来获取详细信息。
注意:debugfs 通常需要手动挂载。
# /sys/kernel/debug 目录不存在或为空,需要挂载 sudo mount -t debugfs none /sys/kernel/debug
查看 zswap 的统计信息:
cat /sys/kernel/debug/zswap/*
你会看到类似以下的输出:
pool: zbud
pool_pages: 1024
pool_pages_max: 32768
same_filled_pages: 512
关键指标解释:
pool_pages:zswap内存池当前占用的页数,一页通常是 4KB。pool_pages_max:zswap内存池曾达到的最大页数,这有助于你判断max_pool_percent设置是否足够。same_filled_pages: 通过same_filled_pages_enabled优化机制节省的页数,这个值越大,说明优化效果越好。stored_pages: 总共存储了多少压缩页。invalid_pages: 因为数据被修改而从池中移除的页数(写时复制)。reject_compress_poor: 因为压缩率太差而被拒绝的页数,如果这个值很高,可能意味着你的工作集不适合压缩,或者压缩算法选择不当。reject_alloc_fail: 因为内存池已满而无法存储新压缩页的次数,如果这个值频繁出现,你可能需要考虑增加max_pool_percent的值。
调优策略与最佳实践
-
从默认开始:
zswap的默认配置在大多数情况下表现良好,除非你遇到性能问题或有特殊需求,否则无需修改。 -
选择合适的压缩算法 (
compressor):- 桌面/通用服务器:
lzo是安全的选择。 - 内存受限服务器:
zstd可以用更少的池空间存储更多数据,减少磁盘 I/O。 - 对延迟极其敏感的系统:
lz4的速度最快。
- 桌面/通用服务器:
-
调整内存池大小 (
max_pool_percent):- 监控
pool_pages_max:运行你的典型工作负载,观察pool_pages_max的值,如果它经常接近或达到pool_pages_max,说明内存池太小,导致频繁的磁盘写入,你应该适当增加max_pool_percent。 - 不要设置过高:设置过高(如超过 50%)会挤占过多可用内存,可能导致系统使用物理内存而不是
zswap,甚至引发 OOM(Out of Memory)。20%是一个很好的起点。
- 监控
-
结合
zram使用:zswap和zram是两个可以协同工作的技术。zswap:作为交换缓存,在物理内存中压缩交换页。zram:创建一个虚拟的块设备,这个设备本身就在内存中进行压缩,你可以将这个zram设备用作交换分区。- 经典组合:
zswap+zram,流程是:内存页 ->zswap(压缩) -> 存入zram(再次压缩) ->zram满了,再写入磁盘 swap,这提供了二级缓存和压缩,可以极大地减少磁盘 I/O,但会消耗更多 CPU 和内存。
-
监控是关键:使用
vmstat,free,sar等工具监控系统的内存、CPU 和 I/O 情况,同时结合/sys/kernel/debug/zswap的信息,才能做出明智的调优决策。
| 参数 | 作用 | 默认值 | 调优建议 |
|---|---|---|---|
enabled |
主开关 | N |
Y (开启), N (关闭) |
pool |
存储后端 | zbud |
zbud (通用), z3fold (高内存利用率) |
compressor |
压缩算法 | lzo |
lzo (平衡), lz4 (快), zstd (高压缩率) |
max_pool_percent |
内存池最大占比 | 20 |
根据内存和负载调整 (10%-30%) |
same_filled_pages_enabled |
优化全同页面 | Y |
保持 Y |
通过理解这些参数并结合实际监控,你可以有效地利用 zswap 来提升 Linux 系统的性能,尤其是在内存有限或磁盘 I/O 成为瓶颈的场景下。
