我设置了 zram 并在我的 Linux 机器中进行了广泛的测试,以衡量它对我的场景是否真的有帮助。但是,我很困惑 zram似乎使用整个未压缩数据大小的内存。当我输入“zramctl”时,我看到:
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 2G 853,6M 355,1M 367,1M 4 [SWAP]
根据zramctl的帮助命令,DATA
是未压缩的大小和TOTAL
包括元数据的压缩内存。然而,当我输入 时swapon -s
,我看到以下输出:
Filename Type size used Priority
/dev/sda2 partition 1463292 0 4
/dev/zram0 partition 2024224 906240 5
906240
是以千字节为单位的已用内存,可转换为DATA
zramctl 的 853,6M 值。这给人留下的印象是,压缩的 zram 设备需要的内存多于它节省的内存。一旦DATA
满了,它实际上开始交换到磁盘驱动器,因此它肯定已满。
为什么zram看似占用了原始数据大小的内存?为什么它不是COMPR
or的大小TOTAL
?网上好像还没有这方面的资料,因为我还没有找到这方面的任何信息。谢谢你!
答案1
因此,经过更多的测试和观察,我有了一些非常有趣的发现。DATA
确实是未压缩的占用交换空间的内存量。但乍一看,它非常具有欺骗性和令人困惑。当您设置 zram 并将其用作交换区时,disksize
并不代表 zram 为压缩数据消耗的内存总量。相反,它代表的是总金额未压缩的zram 将压缩的数据。因此,您可以创建一个大小为 2 GB 的 zram 设备,但实际上 zram 将在总压缩内存约为 500 - 1000 MB 左右后停止(当然取决于您的场景)。像 或 Gnome 的系统监视器这样的命令swapon -s
显示未压缩的zram 设备的数据大小,就像DATA
zramctl 的数据大小。值得庆幸的是,实际上,zram 并没有实际用完报告的内存量。但这意味着在实践中,您实际上必须创建一个 zram 磁盘大小等于您拥有的 RAM + 50% 才能真正利用它,并且不是磁盘大小等于 RAM 大小的一半,就像 zram-config 错误的那样。但请继续阅读以了解更多信息。
这是更深层次的背景:为什么我如此确定?因为我也用 zswap 对此进行了测试。我编译了一个自己的内核,其中与 anon_prio 相比,我降低了 mm/vmscan.c 中的 file_prio 值(在较新的 Linux 5.6 内核中,变量已分别重命名为 fp 和 ap)。减小的 file_prio 值将使内核不再丢弃宝贵的缓存内存。默认情况下,即使设置为vm.swappiness
100,内核也会丢弃大量缓存的 RAM 数据,无论是备用内存还是活动程序。默认配置对性能的影响是极端在内存压力的情况下,当你确实想使用 zram 时,因为那样你绝对想交换的内核很少使用和更频繁地使用高度可压缩的内存方式。可用内存越多,您就有更多空间用于缓存数据。这样缓存的数据就不会以高得离谱的速度被丢弃,Linux 也不必重复地重新读取某些已清除的程序文件缓存。在经典硬盘上进行测试时,您可以轻松验证性能影响。
回到我的 zswap 测试:使用我的自定义内核,一旦我达到 50 - 70% 内存标记,zswap 就会有足够的内存进行压缩。 Gnome 的系统监视器立即显示页面分区的交换数据使用率很高,但奇怪的是,根本没有硬盘驱动器分页!这当然是 zswap 的设计,它会自行交换最近最少使用的内存。但有趣的是系统报告如此高的交换使用率对于交换分区无论如何,最终您会受到交换分区或交换文件大小的限制。即使所有内存都被压缩,您必须至少具有未压缩数据的交换大小。因此,即使实际上 zswap 中的 4 GB 交换内存仅使用 1 - 2 GB,您的交换也需要具有未压缩数据大小的大小。 zram 也是如此,但这里至少没有实际保留内存。好吧,当然,除非您将 zswap 与动态增长的交换文件一起使用。
再说zram,还有一个非常有趣的细节这支持了我的观察:
创建 zram 没有什么意义大于内存大小的两倍 因为我们期望 2:1 的压缩比。请注意,zram 在不使用时大约使用磁盘大小的 0.1%,因此巨大的 zram 是一种浪费。
这意味着要有效使用 zram,您必须至少创建一个等于您安装的 RAM 的磁盘大小。由于压缩率很高,我建议使用 GB RAM + 50%,但上面的引用意味着如果超过 +100%,则没有多大意义。此外,由于我们必须指定与未压缩数据大小相匹配的磁盘大小,因此控制和预测实际的实际内存使用情况要困难得多。从上面有用的官方源中,我们可以TOTAL
使用以下命令限制实际内存使用量(等于zramctl 的值): echo 1G > /sys/block/zram0/mem_limit
。但实际上,这样做会锁定机器。因为系统仍然尝试交换到它,但 zram 施加了限制,并且机器因 CPU 使用率超高而锁定。这种行为根本不可能是故意的,这强化了我的印象,即整个故事的某些部分非常不可靠。
总结一下:
- 您在 zram 设备创建期间设置
disksize
的基本上是虚拟磁盘大小,这确实不是代表实际 RAM 使用情况。 - 您必须预测您的场景的实际 RAM 使用情况(压缩比),或者确保您永远不会创建太大的 zram 磁盘。在实践中,您当前的 RAM 大小 + 50% 应该几乎总是没问题的。
- 不幸的是,Linux 内核的默认配置完全不适合 zram 压缩,即使设置
vm.swappiness
为 100 也是如此。您需要制作自己的自定义内核才能真正制作真实的使用这个方便的功能,因为 Linux 清除了太多的文件缓存,而不是通过交换最可压缩的数据来释放内存很多早些时候。具有讽刺意味的是,有一个有用的补丁可以解决这种情况从未被接受。 - 一旦压缩数据达到该阈值,使用 zram 限制
echo 1G > /sys/block/zram0/mem_limit
将锁定您的系统。您最好使用预测良好的 zram 磁盘大小来限制 zram 使用,因为似乎没有其他替代方案可以限制。