JetBrains Marketplace 上线 UI 冻结报告功能,助力插件开发者排查卡顿
一位用户报告 IDE 停止响应,而你的插件是头号嫌疑对象。你尝试相同步骤,但一切正常。如果没有更多细节,比如在冻结期间捕获的线程转储,就很难知道从哪里入手。
JetBrains Marketplace 现在允许插件作者访问归因于其插件的 UI 冻结报告。要查看这些报告,请打开插件的管理页面,然后选择 Freezes 标签页。
有一个前提:你需要先在插件中启用 Marketplace 报告。希望这个标签页一直保持安静,但值得在需要它之前先配置好。 [LOADING...]
冻结报告中包含什么?
Marketplace 会按错误类型对冻结报告进行分组,并将相似报告收集到报告堆中。每个报告堆会显示一份代表性报告,这样你无需打开每一条记录就能发现重复出现的模式。
自动生成的线程转储摘录会显示被判定为与冻结相关的线程,为你提供一个起点。它也是编码智能体的一个很好的初始输入:简短摘录能帮助它快速定位方向,同时比完整转储消耗更少 token。要进行更深入的调查,请使用 analyze-freeze 技能,然后加入完整转储,以便智能体追踪线程或协程之间的关联。
dump-N.txt 文件包含冻结期间每五秒捕获一次的完整线程转储。根据 IDE 能够捕获的内容,报告还可能包括:
snapshot.jfr,一个 CPU 快照。report.txt,对捕获的线程栈的分析。open-telemetry-metrics.csv,涵盖 VFS 活动、UI 响应性等领域的性能指标。
[LOADING...]
从一份报告开始
打开一份报告,并在其摘录中找到事件调度线程(EDT)。它通常命名为 AWT-EventQueue-0,或包含 EDT。首先,检查 EDT 是正忙于执行高开销工作,还是在等待其他事情完成。
要进一步调查,请下载完整转储,并使用 IDE 中的 Search Everywhere 打开 Analyze Stack Trace or Thread Dump。粘贴转储文本并检查结果。在追踪是什么阻止 EDT 继续推进时,请回头参考原始线程数据。如果有多个转储可用,请比较它们,看看同一操作是否在多个样本中持续出现在栈上。
在下面的示例中,分析器在 org.xml.sax.helpers.XMLFilterImpl.parse 中识别出 EDT 上的文件 I/O。
[LOADING...]
原因也可能出在后台线程上。长时间且不可取消的读操作可能持有写操作所需的锁,导致即使高开销工作在其他地方运行,UI 仍在等待。UI 冻结与后台线程中不可取消读操作的危险详细介绍了这种模式,并解释了如何处理它。
尝试 freeze-analysis 技能
我们的同事 Patrick Scheibe 创建了 analyze-freeze 技能,帮助 AI 编码智能体调查 IntelliJ Platform 线程转储。其中包含有关协程行为、Dispatchers.Default 饥饿以及其他常见冻结模式的指导,并附有修复建议。
试用方法:
- 将 gist 中的
SKILL.md保存到你的调查文件夹中。 - 加入下载的完整线程转储,以及
report.txt和协程转储文本(如果有)。 - 让你的智能体阅读该技能,并使用以下提示词分析这些文件:
在将转储分享给 AI 服务之前,请遵循你所在项目处理诊断数据的流程。使用智能体的解释来指导你的调查,并在做出更改前,将引用的帧与完整转储及你的代码进行核对。
启用 Marketplace 报告
要使用 Marketplace 的内置报告功能,请在 plugin.xml 中注册其错误处理器:
该处理器自 IntelliJ Platform 2023.3 起可用,无需自定义实现。对于支持 Split Mode 的插件,请在前端或共享插件模块中注册它。仅在后台注册不会让前端使用它。 [LOADING...]
用户可以通过 IDE 的错误报告 UI 提交报告,或启用 自动向 JetBrains 发送错误报告,让报告在后台发送。如果 Freezes 标签页为空,请检查你的处理器注册。报告还取决于用户的设置,以及 IDE 是否识别出你的插件与问题有关。
如果你维护自定义报告后端,SDK 错误报告指南解释了面向用户的 ErrorReportSubmitter API,以及用于自动后台报告的实验性 ErrorReportSink API。对于本文介绍的内置 Marketplace 设置,你不需要自定义 sink。
如需视频概览,Patrick Scheibe 的《IntelliJ 插件错误报告究竟如何工作》比较了 Marketplace 报告与自定义 ErrorReportSubmitter。它还介绍了会提交哪些内容,以及为什么附件对冻结报告很重要。
选择修复方案前先检查证据
在将转储与代码对应起来之前,请检查它来自哪个插件版本。版本信息并不总是可用,这会增加识别受影响版本或反混淆栈跟踪的难度。如果缺少版本信息,请将其标记为未知,而不要假设该报告来自你的最新版本。
一旦你找到可能的原因,请重点关注阻止 UI 继续推进的操作。对于长时间的后台读操作,这可能意味着缩短访问模型所花的时间,或选择可取消的读操作 API。将阻塞式 I/O 保持在读操作之外,并确保任何可重新开始的计算都可以安全重试。
通过重复受影响的操作并检查新的诊断证据来测试更改。如果仍然卡住,请在 JetBrains Platform Forum 中提问,并提供 IDE 构建版本、插件版本(如果已知)、相关转储证据以及你已检查过的内容。
即使无法复现冻结,其完整转储也能显示停滞期间 IDE 线程在做什么,并为你提供调查的切入点。如果你的插件已启用 Marketplace 报告,请访问其 Freezes 页面并查看报告;简短摘录可以帮助你决定先看哪里。祝你调查顺利,调试愉快!