Skip to content

正确使用报告浏览器

在你使用命令 /spark profiler 生成了一份分析报告之后,它将会自动上传至浏览器,并以链接的形式呈现在聊天栏。

你可以将这个链接分享给其他用户,例如插件开发者,来帮助分析遇到的问题!

报告浏览器解释

在你第一次见到分析报告的输出时,它可能看起来非常复杂,难以理解。

这有可能是因为 spark 在这个界面中能且仅能提供的信息是其下的类/方法名(例如,开发者在代码中使用的名称),以此描述正在发生的事情。但是,你只需一些常识,稍加思考即可看出报告所表达的内容。

试试看吧!下面是一些名词释义,这可以帮助你更快速地读懂分析报告。😃

线程

当你第一次打开报告浏览器时,你会看见一个被记录的线程列表。

你可以把线程想象成一个在客户端/服务端/等等...干活的工人。以 Minecraft 服务器为例,我们感兴趣的线程一般叫做“服务器线程”,这是服务端用于运行游戏的线程。

img

调用框架(“节点”)

在报告中,我们可以在每个框架下看到三部分信息。即名称、框架与整个线程的占用时间比,以及耗时(只在鼠标移动至其上时显示)。

(在报告底部或顶部显示的)线程总是会显示 100%——这是因为这条线程包含了服务器的所有运算,其余框架都是从主线程分配用量进行各自预算的。

当你在报告中将鼠标移动至节点时,抽样分析在报告生成期间所预测的耗时会在其中的右侧显示。

信息点

一些常见/值得注意的框架调用会在旁边显示一个 ⓘ 信息点 符号。

在这些符号上悬停,浏览器会为你显示一些调用框架有关的额外描述。

img

这些描述是开源的(可以通过社区简单地编辑/改进),如果你注意到某些东西看起来不太对,或者某个线程/方法调用值得加上一段描述,请务必来为我们贡献!😎

展开条目

你可以点击节点,展开并浏览它的子节点。这些子节点会在它下方显示。

img

当在这个示例中展开“服务器线程”时:

  • 它唯一的子节点是 java.lang.Thread.run() - 这是服务器线程的切入点,可以忽略;
  • 这个子节点下的子节点则是 MinecraftServer.run() - 很好!这就是 Minecraft 服务器进程的切入点;
  • 这个字节点下的两个子节点则是 MinecraftServer.tick()Thread.sleep()

正如在“刻循环教程”章节所体积的那样,任何花在休眠(或标有“parked”字样的线程)上的时间都表示服务器正常运行!我们可以先不看这些。

但是,MinecraftServer.tick() 则是我们排除工作的开始点。我们可以点击它来进一步展开。

进一步分析

img

这个时候,我们就可以看到服务器执行的方法被分别展示在了我们的报告中。

我们已经可以看到一些关键词了:

  • WorldServer.doTick() - 很有可能是正在“滴答”世界 - 也许是方块、红石等东西?
  • WorldServer.tickEntities() - 很有可能是正在“滴答”实体 - 猜起来很容易!
  • CraftScheduler.mainThreadHeartbeat() - 这是 CraftBukkit 正在执行定时插件任务;
  • ...诸如此类 - 你可以大胆猜测它们的功能!

当然,如果你不能根据名字得出它的功能或者还需要更多细节(通常是这个)的话:你可以继续展开节点。

找到性能问题的根源

现在你知道如何浏览报告了,找到“掉链子”的部分只需看右侧的数字展开——也就是,每个节点旁边显示的百分比。这些子节点会在它下方显示。

这代表着这部分代码所消耗的时间占比。

所以,如果你继续展开,找到哪一部分有着相对高的百分比——你最终就会找到问题所在!

这部分的示例可以在“卡顿原因寻找教程”章节中找到。

应用反混淆

Minecraft 客户端/服务器混淆(“加密代码,让代码更难被读懂”)了所有的方法和类名。这绝对会是排除问题的一大障碍!

好在,报告浏览器可以加入反混淆(“解密代码”),让我们能重新读懂这些名字。

默认情况下,浏览器会自动检测所需要使用的映射表。但是,如果这不奏效,你可能需要手动选择正确的映射表。

你可以在页面的右上角下拉式菜单栏中找到这一部分的内容。

img

标记特定的调用方法

在分析你的报告时,你可能会注意到一些特别的方法,并想要把它标记,用于之后的排除或展示给其他用户看。

最简单的方法就是“标记”这个方法。

你可以按住 alt 键并左键点击调用的方法来标记它,就像泰拉瑞亚将物品标记为“收藏”那样。

你也可以右键点击调用的方法,然后在弹出的菜单中点击**“Toggle bookmark(标记)”**

img

你会注意到这个方法变成了红色。

额外地,一段参数会显示在网址的末尾,以此“编码”标记。如果你将这个修改过的链接分享给其他用户,那么他们也可以看见你的标记,如果标记在子节点,则会自动展开。

浏览

报告浏览器支持一些不同的浏览(模式)。

你可以通过点击上方控制栏的 👁️ 按钮来切换浏览模式。

浏览全部

此为浏览器的默认浏览模式。这会完整地显示可展开的节点。

直观浏览

直观浏览模式会精简所显示的报告,它会将前 250 个耗时最大的方法排序并显示。这在排除调用时间较长的方法时会很有用。

这个浏览模式下有两个不同的显示模式。

显示模式描述
从上往下调用树“正常”显示——展开一个节点会显示它调用的子方法。
从下往上调用树的显示顺序是倒过来的——展开的一个节点会显示调用了它的方法。

这个浏览模式下有两个不同的排序模式。

排序模式描述
总用时方法会根据它们的“总用时”(方法内执行代码与子级调用所花费时间的和)进行排序。
自用时方法会根据它们的“自用时”(仅方法内执行代码所花费的时间)进行排序。

溯源浏览

若你需要找到性能表现糟糕的插件或模组,溯源浏览模式会很有用。

在这个模式下,报告中会分别显示每个插件/模组的进程。树会在顶部过滤显示它们调用所有的外部方法。

这个浏览模式下有两个不同的合并模式。

合并模式描述
合并签名相同的调用方法会被合并,无视其是否来自相同的调用方法。
分离有相同签名但不是被同一方法调用的方法会分开显示。

火焰图

火焰图是查看报告的一种新兴方式。

这能让浏览器上的内容更加容易被你理解(或者只是理解其中的一部分)。

若要打开火焰图浏览模式,只需要在顶部的控制栏点击“火焰”标志,或者右键点击一个线程/方法调用之后,再在弹出的菜单中选择**“View as Flame Graph(以火焰图浏览)”**

img

如此操作过后,便可打开火焰图浏览模式。

img

在这个模式中,每个节点的长度对应了执行这部分内容所消耗的时间。

你可以点击一个节点来“详细查看”它,这会让这条内容张开并放大显示。其下的子节点也会一并展开。

你可以将鼠标悬浮其上来显示它的完整方法名和其处理用时。

若要退出火焰图浏览模式,返回正常的阅读模式,只需点击在页面右上角的“Exit Flame View(退出火焰图浏览模式)”即可。

img