正确使用报告浏览器
在你使用命令 /spark profiler
生成了一份分析报告之后,它将会自动上传至浏览器,并以链接的形式呈现在聊天栏。
你可以将这个链接分享给其他用户,例如插件开发者,来帮助分析遇到的问题!
报告浏览器解释
在你第一次见到分析报告的输出时,它可能看起来非常复杂,难以理解。
这有可能是因为 spark 在这个界面中能且仅能提供的信息是其下的类/方法名(例如,开发者在代码中使用的名称),以此描述正在发生的事情。但是,你只需一些常识,稍加思考即可看出报告所表达的内容。
试试看吧!下面是一些名词释义,这可以帮助你更快速地读懂分析报告。😃
线程
当你第一次打开报告浏览器时,你会看见一个被记录的线程列表。
你可以把线程想象成一个在客户端/服务端/等等...干活的工人。以 Minecraft 服务器为例,我们感兴趣的线程一般叫做“服务器线程”,这是服务端用于运行游戏的线程。
调用框架(“节点”)
在报告中,我们可以在每个框架下看到三部分信息。即名称、框架与整个线程的占用时间比,以及耗时(只在鼠标移动至其上时显示)。
(在报告底部或顶部显示的)线程总是会显示 100%
——这是因为这条线程包含了服务器的所有运算,其余框架都是从主线程分配用量进行各自预算的。
当你在报告中将鼠标移动至节点上时,抽样分析在报告生成期间所预测的耗时会在其中的右侧显示。
信息点
一些常见/值得注意的框架调用会在旁边显示一个 ⓘ 信息点 符号。
在这些符号上悬停,浏览器会为你显示一些调用框架有关的额外描述。
这些描述是开源的(可以通过社区简单地编辑/改进),如果你注意到某些东西看起来不太对,或者某个线程/方法调用值得加上一段描述,请务必来为我们贡献!😎
展开条目
你可以点击节点,展开并浏览它的子节点。这些子节点会在它下方显示。
当在这个示例中展开“服务器线程”时:
- 它唯一的子节点是
java.lang.Thread.run()
- 这是服务器线程的切入点,可以忽略; - 这个子节点下的子节点则是
MinecraftServer.run()
- 很好!这就是 Minecraft 服务器进程的切入点; - 这个字节点下的两个子节点则是
MinecraftServer.tick()
和Thread.sleep()
。
正如在“刻循环教程”章节所体积的那样,任何花在休眠(或标有“parked”字样的线程)上的时间都表示服务器正常运行!我们可以先不看这些。
但是,MinecraftServer.tick()
则是我们排除工作的开始点。我们可以点击它来进一步展开。
进一步分析
这个时候,我们就可以看到服务器执行的方法被分别展示在了我们的报告中。
我们已经可以看到一些关键词了:
WorldServer.doTick()
- 很有可能是正在“滴答”世界 - 也许是方块、红石等东西?WorldServer.tickEntities()
- 很有可能是正在“滴答”实体 - 猜起来很容易!CraftScheduler.mainThreadHeartbeat()
- 这是 CraftBukkit 正在执行定时插件任务;- ...诸如此类 - 你可以大胆猜测它们的功能!
当然,如果你不能根据名字得出它的功能或者还需要更多细节(通常是这个)的话:你可以继续展开节点。
找到性能问题的根源
现在你知道如何浏览报告了,找到“掉链子”的部分只需看右侧的数字展开——也就是,每个节点旁边显示的百分比。这些子节点会在它下方显示。
这代表着这部分代码所消耗的时间占比。
所以,如果你继续展开,找到哪一部分有着相对高的百分比——你最终就会找到问题所在!
这部分的示例可以在“卡顿原因寻找教程”章节中找到。
应用反混淆
Minecraft 客户端/服务器混淆(“加密代码,让代码更难被读懂”)了所有的方法和类名。这绝对会是排除问题的一大障碍!
好在,报告浏览器可以加入反混淆(“解密代码”),让我们能重新读懂这些名字。
默认情况下,浏览器会自动检测所需要使用的映射表。但是,如果这不奏效,你可能需要手动选择正确的映射表。
你可以在页面的右上角的下拉式菜单栏中找到这一部分的内容。
标记特定的调用方法
在分析你的报告时,你可能会注意到一些特别的方法,并想要把它标记,用于之后的排除或展示给其他用户看。
最简单的方法就是“标记”这个方法。
你可以按住 alt
键并左键点击调用的方法来标记它,就像泰拉瑞亚将物品标记为“收藏”那样。
你也可以右键点击调用的方法,然后在弹出的菜单中点击**“Toggle bookmark(标记)”**
你会注意到这个方法变成了红色。
额外地,一段参数会显示在网址的末尾,以此“编码”标记。如果你将这个修改过的链接分享给其他用户,那么他们也可以看见你的标记,如果标记在子节点,则会自动展开。
浏览
报告浏览器支持一些不同的浏览(模式)。
你可以通过点击上方控制栏的 👁️
按钮来切换浏览模式。
浏览全部
此为浏览器的默认浏览模式。这会完整地显示可展开的节点。
直观浏览
直观浏览模式会精简所显示的报告,它会将前 250 个耗时最大的方法排序并显示。这在排除调用时间较长的方法时会很有用。
这个浏览模式下有两个不同的显示模式。
显示模式 | 描述 |
---|---|
从上往下 | 调用树“正常”显示——展开一个节点会显示它调用的子方法。 |
从下往上 | 调用树的显示顺序是倒过来的——展开的一个节点会显示调用了它的方法。 |
这个浏览模式下有两个不同的排序模式。
排序模式 | 描述 |
---|---|
总用时 | 方法会根据它们的“总用时”(方法内执行代码与子级调用所花费时间的和)进行排序。 |
自用时 | 方法会根据它们的“自用时”(仅方法内执行代码所花费的时间)进行排序。 |
溯源浏览
若你需要找到性能表现糟糕的插件或模组,溯源浏览模式会很有用。
在这个模式下,报告中会分别显示每个插件/模组的进程。树会在顶部过滤显示它们调用所有的外部方法。
这个浏览模式下有两个不同的合并模式。
合并模式 | 描述 |
---|---|
合并 | 签名相同的调用方法会被合并,无视其是否来自相同的调用方法。 |
分离 | 有相同签名但不是被同一方法调用的方法会分开显示。 |
火焰图
火焰图是查看报告的一种新兴方式。
这能让浏览器上的内容更加容易被你理解(或者只是理解其中的一部分)。
若要打开火焰图浏览模式,只需要在顶部的控制栏点击“火焰”标志,或者右键点击一个线程/方法调用之后,再在弹出的菜单中选择**“View as Flame Graph(以火焰图浏览)”**
如此操作过后,便可打开火焰图浏览模式。
在这个模式中,每个节点的长度,对应了执行这部分内容所消耗的时间。
你可以点击一个节点来“详细查看”它,这会让这条内容张开并放大显示。其下的子节点也会一并展开。
你可以将鼠标悬浮其上来显示它的完整方法名和其处理用时。
若要退出火焰图浏览模式,返回正常的阅读模式,只需点击在页面右上角的“Exit Flame View(退出火焰图浏览模式)”即可。