一、我的问题 我的机器是 Ubuntu 22.04.5、内核 6.8,31 GiB 内存(标称 32G),CPU 是 i7-10700,16 个线程。平时开着浏览器、编辑器和几个容器,内存一冲高就卡死,鼠标都拖不动,要等十几秒才缓过
一、我的问题我的机器是 Ubuntu 22.04.5、内核 6.8,31 GiB 内存(标称 32G),CPU 是 i7-10700,16 个线程。平时开着浏览器、编辑器和几个容器,内存一冲高就卡死,鼠标都拖不动,要等十几秒才缓过来。但同一时间 CPU 基本是闲的。 先看了内存和 swap:
只有一个 2 G 的磁盘 swapfile 在兜底。内存一紧,内核就往这块慢盘上倒页,一旦开始来回换页(thrashing),整机就卡住。swappiness 是默认的 60,没有 zram,zswap 也没开。 思路很直接:内存不够、CPU 有余,那就用 CPU 换内存——上 zram。 二、zram 是什么,为什么能换zram 在内存里建一块块设备,写进去的数据先用压缩算法压一遍再存。把它当 swap 用,内核换出的页就被压缩后留在内存里,而不是写到磁盘。匿名页(进程的堆栈、数据这类没有文件后备的内存)通常能压到原大小的三分之一左右,于是同样的物理内存能装下更多内容。代价是每次换出、换入都要花 CPU 做压缩和解压,而这正是我富余的资源。
图 1. zram 作为 swap 时一页内存换出/换入的数据通路,全程在内存内完成。 几个要点:
三、动手配置,以及我踩的坑我用 systemd 的 zram-generator:配置驱动,开机自动重建,最省事。 第 1 步,安装。
第 2 步,写配置。 我照搜到的教程写了下面这版——后面会看到,这版是错的:
第 3 步,一看结果,不对:
31 G 的一半应该是约 15.5 G,怎么只给了 4 G?而且 zstd 和优先级都对——说明配置文件确实被读了,单单尺寸不对。 先确认配置没写错,文件就是 zram-size = ram / 2,没问题。于是去翻日志:
原因出来了:它根本不认识 zram-size 这个键,直接忽略了。再看版本和手册:
手册里只有 zram-fraction 和 max-zram-size,没有 zram-size。zram-size(ram / 2 这种表达式语法)是 zram-generator 较新版本(1.x)才有的写法;Ubuntu 22.04 装的是 0.3.2,只认老键。zram-size 被忽略后,它退回到默认值——zram-fraction 默认 0.5、max-zram-size 默认 4096(MB),于是 min(0.5 × 31G, 4G) = 4G。这就是那 4 G 的来历。 坑就坑在它静默退回默认、只在日志里留一行 Unknown key:照抄新版教程、又不去翻 journal 的人,很容易就拿着一块 4 G 的 zram 以为配好了。 第 4 步,改用这版认识的键:
zram-fraction = 0.5 把逻辑容量设成内存的一半;max-zram-size = 16384(16 G)把默认 4 G 的上限抬上去,否则又会被砍回 4 G。重启服务:
这次对了:15.5 G、zstd、优先级 100,排在磁盘 swapfile(-2)前面。内核会先用 zram,用满了才轮到磁盘。 第 5 步,提高 swappiness。 zram 换页很便宜,我把 swappiness 调高,让内核更早把冷页压进 zram,而不是死撑物理内存直到颠簸:
四、开机自启与持久化不用额外做什么。zram-generator 是 systemd 生成器,每次开机会按 /etc/systemd/zram-generator.conf 自动重建 zram swap;swappiness 写在 /etc/sysctl.d/99-zram.conf 里也是持久的。重启后 zramctl 直接能看到那块 15.5 G 的 zram0。 五、它平时占内存吗?什么时候才被用到配完我有个疑问:开了 15.5 G 的 zram,是不是平时就吃掉了我一大块内存?答案是不会。先看一眼平时空闲时的状态:
图 3. 内存富裕时(占用 37%)swap 用量为 0——zram 已就位但还没被用到,此刻几乎不占物理内存。图中 Swap 总量 18.8 G = zram 15.5 GiB + 磁盘 swapfile 2 G。 两个要点:
要亲眼看它工作,等内存压上去(比如 Memory 涨到 80% 以上)再看这几项:
zramctl 的三列是关键:DATA 是写入的原始数据量,COMPR 是压缩后大小,TOTAL 是含分配器开销的实际内存占用,DATA / TOTAL 就是实际压缩比。还有个常见误读:配了 zram 后,监控里 swap 用量会变活跃,这是正常的——这些"swap"并没有离开内存;判断它是否真起作用,看压缩比,而不是 swap 用量数字。 六、zram 和 zswap 的区别顺带说一下另一个容易混淆的东西 zswap。两者都用压缩省内存,但结构不同。
图 2. zram 自成终点,压缩数据常驻内存;zswap 是磁盘 swap 前的压缩缓存,池满后向磁盘回写。 zram 是一块独立的内存盘,不需要后备磁盘,压缩数据一直在内存里,填满且没有别的 swap 兜底时只能触发 OOM。zswap 是磁盘 swap 前面的一道压缩缓存,必须配合磁盘 swap:页先压进内存池,池满时按冷热把最旧的页解压、写回磁盘。
我的场景是想要一块快的、自给自足的内存 swap,所以选 zram。 七、适用、注意,和实际效果适合用 zram 的情况就是我这种:物理内存紧、CPU 有余量。 几点注意:
实际效果,实话说:zram 不是真的加内存,而是让现有内存靠压缩多装一些、并把 swap 变快。配完之后,内存冲高时不再卡死成那样——以前是往 2 G 磁盘 swap 上颠簸,现在是压进 zram、微秒级就能取回。effective 容量大概多出 8–12 G 量级。但如果工作负载常驻就要超过 32 G,唯一的真解还是加内存条;zram 是缓冲,不是无中生有。 |
2024-04-02
2024-02-26
2023-01-24
2024-09-30
2022-08-15