最近入手了一台新电脑,折腾 Fedora Silverblue(银蓝版)是个很酷的选择,毕竟那套不可变的桌面体验太吸引人了。但说实话,刚装上那几天,我整个人都是懵的。
明明硬件配置不差,8核16线程的CPU,32G内存,平时也就开几个浏览器标签、听听音乐、写写代码,结果任务管理器里 CPU 占用率经常莫名其妙飙到 20%-30%,风扇转得跟直升机起飞一样。更离谱的是,当我切换到 Windows 11 时,系统顺滑得像德芙巧克力,一进 Silverblue 就像被按了0.5倍速。
双系统折腾了这么多年,我从没遇到过这么“玄学”的卡顿。以为是驱动问题,查了;以为是 Wayland 兼容性问题,换了 X11 也没用;最后甚至怀疑是不是系统镜像有问题,重新刷了一次,还是卡。
直到有一天,我在 Reddit 上看到一个帖子,提到了“透明大页(Transparent Huge Pages, THP)”和“ZRAM”在某些场景下会成为 CPU 杀手。抱着死马当活马医的心态,我动手试了。结果你猜怎么着?CPU 占用直接从平均 25% 暴跌到 3%!系统 responsiveness 瞬间回来了。
今天就把这个血泪教训整理出来,希望能帮到同样被 Silverblue 卡顿折磨的小伙伴们。咱们不整那些虚头巴脑的理论,直接上干货,怎么查、怎么关、怎么验证,一步步来。
先别急着改,先看看是不是真的卡
在动手优化之前,咱们得先确认问题所在。Silverblue 的卡顿有时候是综合性的,可能是 GPU 渲染、可能是后台服务,也可能是我刚才提到的内存管理策略冲突。
我推荐的第一个动作,是打开一个终端(在 Silverblue 里,右键桌面选“在终端中打开”很方便),然后输入这个命令,实时监控 CPU 和内存的交换情况:
watch -n 1 'echo "=== THP Stats ===" && cat /sys/kernel/mm/transparent_hugepage/stat && echo -e "\n=== ZRAM Stats ===" && zramctl && echo -e "\n=== Memory Pressure ===" && free -h'
这个命令每秒钟刷新一次,能看到很多关键信息。
当我第一次跑这个命令时,我发现了一个惊人的现象。在 /sys/kernel/mm/transparent_hugepage/stat 里,thp_zero_page_alloc 和 thp_collapse_alloc 的数值在不断跳动,而且 thp_split 的频率也很高。这说明什么?说明内核正在不断地尝试合并大页,然后又因为内存压力或者碎片化问题把大页拆开。这个过程是非常消耗 CPU 的,尤其是在你频繁读写不同大小的内存块时(比如浏览器运行各种 JS 脚本、IDE 加载插件)。
同时,看 zramctl 的输出,我发现 ZRAM 设备 /dev/zram0 正在大量压缩数据。ZRAM 本质上是把一部分物理内存当作压缩的交换分区来用。对于 32G 内存来说,其实完全没必要开启 ZRAM,除非你内存只有 8G 或者更小。Silverblue 默认配置里可能为了“通用性”或者某些嵌入式场景开启了它,但这在高性能桌上机上就是个累赘。CPU 在做压缩和解压缩的时候,那些 cycles 白白丢掉了。
为什么透明大页(THP)会成为性能杀手?
很多人听到“大页”两个字,第一反应是“大页肯定快啊,减少 TLB miss 嘛”。这话没错,在数据库、高性能计算这种大块内存连续分配的场景下,THP 确实能提升性能。
但是,普通桌面工作负载完全不是这么回事。
想象一下,你正在用 VS Code 写代码,同时浏览器开着几十个标签。这些进程的内存分配模式是高度碎片化的:一会儿分配一个几 KB 的对象,一会儿释放,一会儿又分配一个大的字体缓存。如果开启 THP,内核会尝试把零散的物理页合并成一个 2MB 的大页。
问题来了:合并需要时间,需要 CPU 介入去扫描、复制、映射。更糟糕的是,如果后续某个进程只访问这个 2MB 大页里的一小部分,其他部分变成了“热点空白”,内核为了节省内存,可能又会把这个大页拆分(split)掉。这一合一分,CPU 就在那儿空转了。
在我的实测中,关闭 THP 后,系统的 mm 线程(内存管理相关)CPU 占用明显下降。你可以用 top -p $(pgrep -f "kswapd|khugepaged") 看看,khugepaged 就是负责大页合并的那个内核线程,它经常占用着不低的 CPU 资源。
为什么 ZRAM 在桌面端可能是个坑?
ZRAM 的优点是减少磁盘 I/O,把内存当 Swap 用,速度快于 SSD。这听起来很美好,对吧?
但对于拥有 32G+ 内存的 Silverblue 用户来说,这几乎是个多余的功能,甚至是个负担。
首先,压缩和解压缩本身就需要 CPU 算力。ZSTD 算法虽然快,但也不是免费的午餐。当你系统内存充裕时,根本不需要 swap,ZRAM 处于空闲状态还好;但一旦有些进程稍微激进一点,开始往 ZRAM 里挤数据,CPU 就得跟着忙活。
其次,ZRAM 会干扰 Linux 的内存回收策略。内核在决定什么时候该回收内存、什么时候该 swap 时,会考虑到 ZRAM 的存在。这可能导致一些本可以在物理内存中驻留的热数据被错误地压缩进 ZRAM,然后再被换出来,造成不必要的延迟。
在双系统环境下,Windows 那边内存管理非常成熟且激进,而 Linux 这边如果配置不当,两者切换时的内存状态重置也可能带来额外的开销。关闭 ZRAM 后,系统会直接使用物理内存,内存压力测试显示响应时间更稳定。
终极优化:如何关闭 THP 和 ZRAM
好了,理论说完了,咱们直接上操作。这一步非常关键,操作不当可能导致系统不稳定,所以请大家一定仔细看。
第一步:禁用透明大页(THP)
禁用 THP 最推荐的方式是创建 systemd 服务,这样在每次启动时都会自动生效,而且比较干净。
- 打开终端,创建一个新服务文件:
sudo rpm-ostree install tuned
注:Silverblue 是不可变系统,有些修改需要通过 rpm-ostree 或者在 /etc/ 下创建配置。对于 THP,我们推荐用 tuned 或者直接在启动脚本里设置。这里我们用更直接的 sysfs 方式配合 systemd。
创建服务文件:
sudo tee /etc/tmpfiles.d/thp.conf << 'EOF'
# Configure transparent huge pages
w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
w /sys/kernel/mm/transparent_hugepage/defrag - - - - never
EOF
然后重启系统。或者,如果你想立即生效(不重启),可以手动执行:
sudo sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
sudo sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
注意:手动执行的方式在重启后会失效,所以必须配合上面的 tmpfiles.d 或者创建一个 systemd service 来确保永久生效。
创建一个 systemd service 确保重启后也生效:
sudo tee /etc/systemd/system/disable-thp.service << 'EOF'
[Unit]
Description=Disable Transparent Huge Pages
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable disable-thp.service
sudo systemctl start disable-thp.service
第二步:禁用或调整 ZRAM
Silverblue 默认可能没有启用 ZRAM,但如果你发现 zramctl 有输出,说明它开了。我们要把它关掉。
- 查找 ZRAM 相关的服务或模块:
systemctl list-unit-files | grep zram
lsmod | grep zram
- 如果找到了服务(比如
zram-generator),禁用它:
sudo systemctl disable --now zram-generator.service
# 或者如果是通过 kernel 模块加载的
sudo modprobe -r zram
- 为了防止它再次被加载,可以创建一个黑名单配置:
sudo tee /etc/modprobe.d/zram-blacklist.conf << 'EOF'
blacklist zram
EOF
如果你是通过
zram-generator配置的,还需要编辑它的配置。通常配置文件在/usr/lib/dracut/modules.d/99zram或者/etc/systemd/zram-generator.conf。检查并注释掉或移除相关配置。更新 initramfs 并重启(因为是 Silverblue,可能需要):
sudo rpm-ostree kargs --append='zram.enabled=0'
sudo rpm-ostree upgrade
sudo reboot
注:zram.enabled=0 这个内核参数在某些版本可能不生效,最稳妥的还是禁用服务+黑名单模块。
第三步:验证优化效果
重启之后,咱们再来跑一次之前的监控命令:
watch -n 1 'echo "=== THP Stats ===" && cat /sys/kernel/mm/transparent_hugepage/stat && echo -e "\n=== ZRAM Stats ===" && zramctl && echo -e "\n=== Memory Pressure ===" && free -h'
这时候,你应该看到:
thp_defrag和thp_collapse_alloc等数值不再频繁跳动,或者增长速度大幅放缓。zramctl返回空,或者没有/dev/zram0设备。free -h显示内存使用更自然,没有大量压缩数据占据空间。
接下来,打开你的常用应用,比如浏览器、IDE,观察 top 命令下的 CPU 占用。我个人的实测数据是:
- 优化前:空闲时 CPU 占用 15-25%,多任务切换时有明显卡顿感,风扇噪音持续。
- 优化后:空闲时 CPU 占用 2-5%,多任务切换丝滑,风扇只有在真正高负载(如编译代码)时才高速运转。
一些额外的 Silverblue 优化小贴士
除了关闭 THP 和 ZRAM,还有一些小技巧能让你的 Silverblue 体验更佳:
使用
tuned服务: Silverblue 默认可能使用的是balanced配置文件。你可以尝试切换到desktop或latency-performance配置:sudo tuned-adm profile desktop这会自动调整 CPU 频率调度、I/O 调度器等参数,对桌面响应速度有提升。
检查 Wayland 兼容性问题: 如果你发现某些应用(尤其是老版本的 Java 应用或某些游戏)在 Wayland 下表现不佳,可以尝试在登录界面切换到 X11 会话。虽然 Wayland 是未来,但兼容性仍然是个问题。
保持系统更新: Silverblue 的优势在于原子更新。定期执行
rpm-ostree upgrade可以确保你拿到最新的内核和优化补丁。内核版本对内存管理和 THP 的支持一直在改进,新内核可能已经对默认配置做了更好调整。清理无用容器和镜像: Silverblue 用户可能喜欢用 Toolbox 或 Chiado 跑容器。长期使用会积累大量容器镜像,占用磁盘空间。可以用
podman system df查看空间使用情况,并用podman system prune清理。
总结
Fedora Silverblue 是一款优秀的操作系统,它的不可变性带来了稳定性和安全性。但在默认配置下,对于一些特定硬件和工作负载,它可能不是那么“跟手”。
透明大页和 ZRAM 本意是优化性能,但在桌面交互场景下,反而可能成为 CPU 的负担。通过关闭它们,我们让内核把精力花在真正该花的地方,系统自然就更流畅了。
我的这次优化,从发现问题到解决问题,不到半小时。希望这篇指南能帮你省去摸索的时间,让你的 Silverblue 双系统体验更加完美。
如果你尝试后还有其他问题,或者有不同的优化心得,欢迎在评论区交流。毕竟,开源社区的魅力就在于大家一起把系统玩得更好嘛!
最后提醒一下:修改系统配置前,最好先了解清楚每一项改动的含义。虽然我提供的方案是经过实测验证的,但每台机器情况不同,建议先小范围测试。祝你优化愉快!
