目录

Linux桌面内存优化

zswap 是 ram 和 swap 的缓冲层, 当系统向 swap 写入数据时, zswap 会先压缩数据放到内存, 如果内存压缩满足一个阈值, 才会真正往 swap 写入数据; zram 是将内存的一部分配置为 swap, 系统向 swap 写入时就会向 zram 配置的内存段用 zstd 压缩后写入, 相当于扩展了一部分内存.

关于 zswap 和 zram 的争论很多, 比较新的 Linux 内核都支持 zstd 和 zsmalloc, 所以和 zram 效率大部分情况是一致的, 所以如果使用 SSD, 可以配置 swap 的话, 个人推荐配置 zswap, 如果不想由于 swap 交换磨损 SSD, 或者树莓派/手机等内置存储速度较慢的设备, 可以使用 zram 优化运行速度.

需要注意这两种技术都会带来压缩时的 CPU 消耗, 需要根据设备使用情况抉择.

zswap 需求 swap, 首先创建 Swap 文件, 在 Btrfs 中, 最好将 swapfile 配置在独立子卷中, 防止 snapper 之类的快照创建失败或者包含 swapfile, 下面以 EndeavourOS 的默认分区威力, 进行 swap 的配置.

首先创建挂载点:

sudo mkdir /mnt/btrfs-root

之后挂载 btrfs 根:

sudo mount /dev/nvme0n1p7 /mnt/btrfs-root -o subvolid=5

硬盘分区根据实际来配置, 注意 -o subvolid=5 是指定配置挂载顶级根, 如果看到如下输出, 证明挂载到了顶级根:

❯ ls /mnt/btrfs-root
@  @cache  @home  @log  @swap

如果不加 -o subvolid=5 也能挂载到顶级根, 是因为 EndeavourOS 默认没有修改 Btrfs 的 default subvolume, 如果以后不小心执行了 btrfs subvolume set-default,就必须显式指定 subvolid=5 才能看到这些子卷了.

之后创建 swap 专用子卷:

sudo btrfs subvolume create /mnt/btrfs-root/@swap

之后创建 swap 文件:

sudo btrfs filesystem mkswapfile --size 8G --uuid clear /mnt/btrfs-root/@swap/swapfile

之后可以卸载挂载点了:

sudo umount /mnt/btrfs-root

之后在 /etc/fstab 添加以下行配置:

# swap mount
UUID=7ceb9efa-5de0-4577-9b6f-ef386a5eff38 /swap btrfs subvol=/@swap,noatime 0 0
/swap/swapfile  none  swap  defaults 0 0

最后创建挂载点并挂载:

sudo mkdir /swap                # 创建挂载点
sudo mount /swap                # 挂载子卷
sudo swapon /swap/swapfile      # 启用 Swap

使用 swapon --show 命令可以查看当前配置的 swap.

调整大小需要删除之前配置的 Swap, 首先关闭 Swap:

sudo swapoff /swap/swapfile

使用 swapon --show 命令可以确认关闭成功.

删除 swapfile:

sudo rm /swap/swapfile

之后可以根据上述步骤创建新的 swapfile.

根据上面的对比, 配置 zRam+Swap 的方案, zswap 是大部分现代 Linux 发行版内核自带的功能, 只需要配置内核参数即可, 我使用 EndeavourOS+systemd-boot, 所以在 /etc/kernel/cmdline 修改内核参数, 每次更新内核都会先读取这里面的参数, 使用 systemd-boot 的 Fedora 也是在这里, systemd-boot 且手动管理内核参数, 应该会在 /boot/loader/entries/ , 如果使用 Grub, 则在 /etc/default/grub 修改. 找到对应的文件, 加入以下内核参数:

zswap.enabled=1 zswap.compressor=zstd zswap.zpool=zsmalloc zswap.max_pool_percent=25

zswap.enabled=1 是启动 zswap 的标志, zswap.compressor=zstdzswap.zpool=zsmalloc 是配置压缩算法和内存分配器, zstd+zsmalloc 是目前最强的组合, 一般不需要修改, zswap.max_pool_percent 一般配 20-40 就可以, 根据自己需求配置.

接下来配置内存管理倾向, 在 /etc/sysctl.d/99-zswap.conf 加入以下配置:

vm.swappiness=100

vm.swappiness=100 会让内核更加积极地把内存放到 swap, 这样可以尽量使用 zswap 来压缩内存, 默认值为 60, 比较旧的内核范围是 0-100, 新版内核是 0-200.

最后运行命令重新装载内核, 如果是在 /etc/default/grub/boot/loader/entries/ 直接修改参数则不需要这一步.

sudo reinstall-kernels

待补充…

uresourced 是 Fedora 开发的, 用来为当前活跃的用户会话预留资源的守护进程

systemd-oomd 是 systemd 自带,基于 Cgroups v2 和 PSI 杀进程的守护进程, Linux 内核自带的 OOM Killer 反应较慢,往往在系统已经卡死很久后才动作,因此用户态的 OOM 守护进程是提升用户桌面体验的必备组件

接下来安装和启用这两个组件

yay -S uresourced
sudo systemctl enable --now uresourced
sudo systemctl enable --now systemd-oomd

接下来修改 systemd-oomd 配置, 在 /etc/systemd/system/user@.service.d/override.conf 修改用户配置:

[Service]
ManagedOOMMemoryPressure=kill
ManagedOOMMemoryPressureLimit=50%

其它遵循默认配置即可, 默认配置已经很合理, 严格来说只需要 ManagedOOMMemoryPressure=kill 即可, ManagedOOMMemoryPressureLimit=50% 是默认值, 但是为了方便后面调整数值还是写上比较好.