← 返回博客

修复 Git Blame 卡顿问题

2024年5月6日

我们刚完成修改,我运行了 git commit,Zed 立刻卡住了,开始出现 沙滩球…,10秒后才恢复正常。

我再次尝试:修改,git commit,又出现了沙滩球。不妙。

Zed 理应很快。到底怎么回事?

我们打开 Instruments,运行了一个 CPU 性能分析。

macOS Instruments showing a Severe Hang, and no CPU usage.
macOS Instruments 显示严重的卡顿,并且没有 CPU 使用率。

嗯…我们的进程在…什么都没做…?这不合理。至少 Instruments 同意这是一个“严重卡顿”。

Mikayla 搜索了一下,找到了 这篇文章,建议我们尝试“线程状态”工具。

Thread State instruments showing the main thread is blocked.
线程状态工具显示主线程被阻塞。

这很有趣,主线程确实被阻塞了(几乎所有后台线程也是)。但为什么呢?

偶然发现左侧下拉菜单中的“OS Fundamentals”子工具,我们找到了答案。

OS Fundamentals sub-instrument showing a psynch_cvwait syscall
OS Fundamentals 子工具显示一个 psynch_cvwait 系统调用

它卡在系统调用 psynch_cvwait 中。这是一个条件变量等待,但它在等待什么呢?我们的后台线程似乎也什么都没做…

通过点击最右下角的图标查看堆栈跟踪,我们得到了一点线索,但这更像是“不应该发生的事情”。

Backtrace from the main thread
主线程的回溯

看起来主线程正在有意地阻塞在 block_with_timeout 中。我们在几个地方这样做,以确保如果能快速完成用户可见的任务,结果会在下一帧显示。话虽如此,超时设置为 5ms,这样如果任务花费的时间比预期长,我们不会阻塞 UI 线程。在这种情况下,我们阻塞了 4550ms,这,查看记录,大概是太长了1000倍。

把这个问题放到一边:为什么主线程在 5ms 后没有被唤醒?我们继续在 Instruments 中点击。

查看右下角的 Narrative 视图,我们得到了第一个真正的线索。

The Narrative around the time the thread was unblocked
线程解除阻塞时的叙述

“线程被 git 唤醒。”有趣。考虑到我是用 git commit 触发的,git 在运行并不奇怪,但它会阻塞 Zed 就很奇怪了。

通过 git 过滤 Narrative 视图,我们发现了一个更有趣的事情。看起来几乎每次我们的应用程序被唤醒时,都是被 git 唤醒的,不仅如此,每次都是不同的 git 进程。我们有 257 个 git 进程在运行?!

A large number of git process-swaps in the Narrative
Narrative 中大量的 git 进程切换

我们在这个领域最近添加的功能是 内联 Git Blame,所以它是主要嫌疑人。果然,禁用它就解决了问题。

从那时起,追踪问题就相对容易了。当我们添加 git blame 代码时,是为了为 gutter 提供支持,因此假设它一次会在一两个文件中打开。我们设置了一堆事件监听器,以便如果 git 索引更改,责怪信息就会更新。

不幸的是,由于 git blame 现在为每个文件都启用了,并且我们打开了 257 个文件,所以每次我通过提交更改 git 索引时,Zed 都会同时生成 257 个 git 进程。哎呀!(现已修复…)。

这只剩下为什么主线程在 5ms 后没有被唤醒的谜团。我认为问题的一部分是争用——我们的进程树正在尽其所能地生成 git 进程——但这并不是全部。

为了在几毫秒后唤醒主线程,我们启动了一个后台任务,该任务休眠所需时间,然后(通过条件变量)向主线程发出信号以恢复。不幸的是,macOS 上的 GPUI 计时器以低于后台任务的优先级运行。经典的优先级反转:主线程正在等待优先级最低的任务,而该任务又被我们所有的 git 进程阻塞。又一个哎呀!(也已修复…)。

我们为 Zed 的速度感到非常自豪,当我们不小心让它变慢时,确实有点尴尬。话虽如此,深入挖掘并找出问题所在总是很有趣的。

这些修复已随 v0.133.7 发布,同时修复了我们使用 新监控工具 发现的一些其他卡顿问题(后续将发布博文!)。

如果您的 Zed 出现沙滩球卡顿,请提交问题,我们很乐意与您一起深入研究并找出问题所在。


正在寻找更好的编辑器吗?

您今天就可以在 macOS、Windows 或 Linux 上试用 Zed。立即下载


我们正在招聘!

如果您对我们博客中涵盖的主题充满热情,请考虑加入我们的团队,帮助我们实现软件开发的未来。