Chromium FD 耗尽问题(Linux 下歌词动画卡死)
如果你在 Linux 上长时间播放后,歌词动画突然定格、画面不再更新,而音乐还在正常播放,多半就是这个问题。 它来自 Folia 使用的 Chromium 内核,升级 Electron 也无法避免。最快的解决办法是提高系统的 FD 和内存映射上限, 不会改变任何视觉效果;Folia 自己也默认改变了部分发光的绘制方式来绕开它。
现象
- 只在 Linux 上会卡死。通常连续播放 30~40 分钟后出现,具体时间取决于当前的歌词动画模式和帧率。
- 卡死时歌词和背景都停在某一帧,但音频、进度和快捷键仍然有效。
- 重启 Folia 后恢复(切换歌词动画模式不会恢复),播放一段时间后又会再次出现。
原因
部分歌词动画会让发光的模糊半径,或者文字在屏幕上的实际尺寸逐帧变化。Chromium 每遇到一个新的"字形 × 尺寸 × 模糊" 组合,都会在共享内存里新占一小块,并且不归还。每一块都会占用一个文件描述符(FD)。
Linux 默认只允许一个进程同时打开 1024 个 FD。渲染进程用完之后就无法再分配共享内存,画面随之停止更新。 Windows 和 macOS 上同样会占用这部分内存,但没有这么低的上限,每天只多几 MB,不会卡死。
受影响的是带逐字发光或镜头缩放的歌词动画模式:流光、云阶、心象、回环和浮名。
解决办法
有两种办法,任选其一即可。
方法一:提高系统上限(最快,不改变任何视觉效果)
问题的根源是渲染进程默认只有 1024 个 FD。把这个上限提高,Folia 就不会再卡住,所有歌词动画保持原样。
提高 systemd 给用户会话的 FD 软上限。新建下面两个文件,内容相同:
/etc/systemd/system.conf.d/90-nofile.conf和/etc/systemd/user.conf.d/90-nofile.confini[Manager] DefaultLimitNOFILE=524288:524288提高内存映射数量上限。每个 FD 同时对应一块内存映射,FD 上限放开后,下一个会被用完的是这个上限 (不少发行版默认 65530,大约连续播放 30 小时后耗尽):
bashecho 'vm.max_map_count = 1048576' | sudo tee /etc/sysctl.d/90-max-map-count.conf sudo sysctl --system重启电脑,或至少注销后重新登录,让新的上限对桌面会话生效。
确认是否生效:重新登录后打开终端执行 ulimit -Sn,显示 524288 就说明桌面会话里启动的程序(包括 Folia) 都拿到了新的上限。
这个办法不会阻止占用继续增长,只是让上限远到用不完:以每秒不到 1 个 FD 计算,渲染进程和 GPU 进程每小时各多占 约 10 MB 共享内存,退出 Folia 后全部释放。采用这个办法后,可以把下面的实验室开关关掉,保留原来的发光效果。
方法二:实验室开关
设置 > 选项 > 实验室 > 修复 Linux 歌词动画卡死,也可以在命令面板里搜索歌词卡死直接切换。
- Linux 上默认开启,不需要修改系统设置就能避免卡死。
- 其它平台默认关闭:这个问题在那里不会导致卡死,没有必要改变绘制方式。
- 开启后,上述模式的发光改用不会触发这个问题的方式绘制,外观与原来非常接近,但不是逐像素完全一致。
确认是否是这个问题
桌面版可以在 设置 > 选项 > 开发者 > 内存监控 打开监控窗口。Linux 上窗口里会画出 Renderer fds 和 GPU fds 两条曲线:
- 开关开启时,播放过程中这两条曲线应当基本是平的。
- 开关关闭时曲线会持续上升;如果已按方法一提高了上限,这是预期的,不会卡死。
仍然卡死怎么办
- 确认方法一的上限已经生效,或者
实验室里的修复 Linux 歌词动画卡死是开启状态。 - 打开
内存监控播放几分钟,记下 FD 曲线是否上升、当时使用的是哪个歌词动画模式和背景。 - 带着这些信息到 GitHub Issues 反馈。