V8 CPU 与内存分析
使用 GoLand,您可以利用 V8 的基于采样的分析器 捕获并分析 Node.js 应用程序的 CPU 分析和堆快照。
您还可以打开并浏览通过 Google Chrome DevTools 捕获的您的客户端代码的快照。
开始之前
请在 设置 | 插件 页面、 Marketplace 选项卡中安装并启用 Node.js 插件,具体操作请参见 从 JetBrains Marketplace 安装插件。
CPU 分析
CPU 分析有助于更好地了解代码中哪些部分占用了最多的 CPU 时间,以及 V8 JavaScript 引擎如何执行和优化您的代码。
GoLand 中的 Node.js CPU 分析基于 V8 内置 CPU 分析器,它可提供有关代码执行及 JavaScript 引擎本身行为的信息,包括垃圾回收周期、编译与重新编译及代码优化等。
分析器会在特定时间间隔拍摄快照,这些间隔称为 tick。 不仅会对代码执行进行测量,还会测量引擎本身执行的操作,例如编译、调用系统库、优化以及垃圾回收。
启用 CPU 分析
若要在应用启动时启用 V8 CPU 分析,您需要在 Node.js 运行配置中指定额外的设置。
转到 。 或者,也可以从工具栏中的 运行 小部件中选择 编辑配置。

在打开的 编辑配置 对话框中,点击工具栏上的 添加 按钮(
),然后从列表中选择 Node.js。
从列表中选择用于启用 CPU 分析的 Node.js 运行配置,或根据 运行和调试 Node.js 描述创建新配置。
切换到 V8 分析 选项卡,并选中 记录 CPU 分析信息 复选框。 在 日志文件夹 字段中指定已记录日志的存储文件夹路径,日志文件命名为
isolate-<session number>。
收集 CPU 分析信息
在主工具栏的列表中选择运行配置,然后点击
,或从主菜单中选择 。
在需要分析的场景执行后,点击工具栏中的
以停止该进程。
分析 CPU 分析日志
当您停止应用程序时,GoLand 会自动打开 V8 分析 工具窗口,并显示其中收集的分析数据。 如果该窗口已打开并展示了其他会话的收集数据,GoLand 会打开一个新选项卡。 自动打开的选项卡以控制应用程序执行及分析数据收集的运行配置命名。
要打开并分析之前保存的分析数据,请转到 (或按 Ctrl+Shift+A ),开始输入 V8 ,然后从列表中选择 分析 V8 分析日志。

然后选择相关的 V8 日志文件 isolate-<session number>。 GoLand 会以所选日志文件的名称创建一个独立的选项卡。
基于收集到的分析数据,GoLand 构建三棵调用树,并分别在独立面板中显示。 利用这些调用树,您可以从两个角度分析应用程序的执行情况:一是识别耗时的调用(“heavy”),二是了解“谁调用了谁”。
理解调用树中的指标
调用树使用 Total 和 Self 指标来表示函数中的 ticks 数量或其占总执行时间的比例:
Total 表示在函数及其调用的函数中所花费的总时间。
Self 表示仅在该函数自身内部所花费的时间,不包括其子节点。
Of Parent 指标显示某个函数的纯执行时间与其调用方函数(Parent )的执行时间的比例。
V8 优化器
在某些情况下,V8 可以优化您的代码。 有关详细信息,请参阅 Optimizing for V8。
函数名称前的星号
*表示该函数已被优化。波浪号
~表示该函数可能需要优化但尚未被优化。 引擎可能会延迟优化,或者在代码运行时间很短时跳过优化,然而波浪号指示代码可重写以获得更好性能的位置。
最高调用树
顶层调用 面板列出已执行的操作,按 Self 指标的降序排列。 对于每项操作,显示其 Total、 Total% 和 Self% 指标。 对于每个函数调用,GoLand 会显示函数定义所在的文件名、行号与列号。

概览 面板中的图表展示 Self 时间在 Self% 指标高于 1% 的调用中的分布情况。
自底向上调用树
自下而上 面板还按 Self 指标的降序列出已执行的操作。 与 顶部调用 面板不同, 自下而上 面板仅显示 Total% 指标高于 2 的操作及其调用函数。
每个活动均显示其以 tick 为单位的执行时间以及 Of Parent 指标。
对于每个函数调用,GoLand 会显示函数定义所在的文件名、行号与列号。

自顶向下调用树
自上而下 面板显示完整的调用层次结构,入口函数显示在顶部。 对于每项操作,显示其 Total、 Total%、 Self 和 Self% 指标。 对于每个函数调用,GoLand 会显示函数定义所在的文件名、行号与列号。

浏览调用树
要导航至函数的源代码,请选择此函数并按工具栏上的 F4 或
,或者从上下文菜单中选择 跳转到源代码。
要切换至其他面板并从不同视角查看调用,请选择该调用,然后从其上下文菜单中选择 导航至 ,再选择目标。 GoLand 将切换到所选面板,并将焦点移至该调用。
展开或折叠节点
当 GoLand 为分析会话打开选项卡时,默认会展开包含最大调用消耗的节点。 在查看调用树时,您可能希望折叠某些节点或展开其他节点。
要展开或折叠某个节点,请在其上下文菜单中选择 展开节点 或 折叠节点。
要折叠活动面板中的所有节点,请点击工具栏上的
。
要还原原始树结构显示,请点击
。
筛除低开销调用
执行此操作以仅查看实际引发性能问题的调用。
点击工具栏上的
,然后使用滑块指定要显示的调用的最小 Total% 或 Parent% 值,最后点击 完成。
保存并比较分析数据
要保存一行函数及其指标数据,请在该函数的上下文菜单中选择 复制。 如果您希望比较某个函数在两个会话中的测量结果,例如在优化代码后,这一操作可能会很有帮助。
要仅保存函数名称及其定义所在的文件名称,请在该函数的上下文菜单中选择 复制调用。
要将某项内容与剪贴板的内容进行比较,请在该项的上下文菜单中选择 与剪贴板比较。 GoLand 会打开 Diff Viewer。
要将当前日志与另一个 isolate 进行比较,请点击工具栏上的
。 在打开的对话框中,选择要用于与当前快照进行比较的 isolate。 为缩小搜索范围,请指定目标 isolate 是在当前 isolate 之前还是之后生成的。
导出调用树
要将当前窗格中的调用树保存为文本文件,请点击工具栏上的
,并在打开的对话框中指定目标文件。
分析 Flame 图
使用多色 火焰图 查找应用暂停的位置,并探索导致这些暂停的调用。

图表由四个区域组成:
顶部区域显示一个时间轴,带有两个滑块,用于限制要调查的片段的起始和结束位置。
底部区域以多色图表的形式显示调用堆栈。 首次调用时,每个函数都会被分配一个随机颜色,随后该函数在当前会话中的每次调用都会以此颜色显示。
中部区域显示来自 垃圾回收器 、引擎、外部调用以及执行本身的调用摘要。 这些活动所使用的颜色显示在该区域的顶部。
右侧窗格列出了所选片段中的所有调用,对于每次调用,该列表显示其持续时间、被调用函数的名称以及定义该函数的文件。
底部区域和右侧区域是同步的:当您在底部区域拖动滑块浏览时间轴时,右侧窗格中的焦点会移动到每一时刻执行的调用处。
此外,如果您点击底部区域中的某个调用,滑块会自动移动到该位置,右侧窗格中的焦点也会切换到相应函数,如有必要,列表也会自动滚动。 反之亦然,如果您点击列表中的某项,GoLand 会自动在底部区域中选择相应的调用,并将滑块移至该位置:
在时间轴中选择片段
要探索某一时间段内的流程,您需要在时间轴中选择相应的片段。 为此,拖动滑块或点击两个滑块之间的 窗口 ,并将其拖动到所需片段。
无论哪种方式,下方的多色图表都会显示所选片段内的调用堆栈。
要放大图表,请点击所选片段,然后点击工具栏上的
。 GoLand 会打开一个新选项卡,并将所选片段放大以适配选项卡宽度,使您能够更详细地检查该片段。
浏览 Flame 图
在右侧区域中的调用列表中,您可以跳转到被调用函数的源代码、工具窗口的其他窗格以及火焰图中包含特定指标的区域。
要跳转到被调用函数的源代码,请在调用的上下文菜单中选择 跳转到源代码。
要使火焰图放大至包含调用特定指标的片段,请选择该调用,在其上下文菜单中选择 导航至 ,然后选择指标。
您还可以跳转到调用的堆栈跟踪,查看并分析异常。 为此,请在调用的上下文菜单中选择 以堆栈跟踪显示。 GoLand 会在单独的选项卡中打开堆栈跟踪,若要返回 火焰图 窗格,请点击底部的 V8 CPU 分析 工具窗口按钮。
内存分析
内存分析可帮助您检测内存泄漏和动态内存问题,并定位导致这些问题的代码片段。
启用内存分析
要在应用启动时自动获取内存快照,您需要在 Node.js 运行配置中指定其他设置。
转到 。 或者,从工具栏上的 运行 小部件中选择 编辑配置。

在打开的 编辑配置 对话框中,点击工具栏上的 添加 按钮(
),然后从列表中选择 Node.js。
从列表中选择要启用 CPU 分析的 Node.js 运行配置,或按照 创建 Node.js 运行/调试配置 中的说明创建新配置。
切换到 V8 分析 选项卡,并选中 允许创建堆快照 复选框。
收集内存分析信息
在主工具栏中从列表选择运行配置,然后点击
或从主菜单中选择 。
在应用执行期间的任意时间,点击
,位于 运行 工具窗口的工具栏上。
在打开的对话框中,指定快照的名称以及保存文件夹的路径。 要立即开始分析快照,请选中 打开快照 复选框。
分析内存快照
当您获取快照并选择进行分析时,GoLand 会打开 V8 堆 工具窗口,并显示收集到的数据。 如果该窗口已打开并显示其他会话的收集数据,GoLand 会打开一个新选项卡。
要打开并分析之前保存的内存分析数据,请转到 (或按 Ctrl+Shift+A ,开始输入 V8 ,并从列表中选择 分析 V8 堆快照)。

然后选择相关的 .heapsnapshot 文件。 GoLand 会创建一个以所选文件命名的单独选项卡。
该工具窗口包含三个选项卡,从不同视角展示收集到的信息。
包含关系 选项卡展示应用中的对象,按以下几个顶层条目进行分组: DOMWindow 对象、 原生浏览器对象 以及 GC 根节点 ,即 垃圾回收器 实际使用的根节点。 有关详细信息,请参阅 Containment View。
对于每个对象,该选项卡显示它与 GC 根节点的距离 ,即对象与 GC 根节点之间的最短简单节点路径,以及该对象的 浅层大小 和 保留大小。 除了显示对象大小的绝对值,GoLand 还会显示其占用内存的百分比。
占用空间最大的对象 选项卡显示内存占用最多的对象,并按其 保留大小 进行排序。 在此选项卡中,您可以发现由于在某些全局对象中积累数据而导致的内存泄漏。
摘要 选项卡显示按类型分类的应用程序对象。 该选项卡显示每种类型的对象数量、其大小以及它们所占用内存的百分比。 此信息可能揭示内存状态的线索。
每个选项卡都包含一个 详细信息 面板,显示从 GC 根到当前选中对象的路径,以及对象的 retainers 列表,即那些保留对选定对象引用的对象。 每个堆快照都包含大量“反向”引用和循环,因此每个对象通常有多个 retainer。
使用文本标签标记对象
标签可帮助您区分对象,并在对象之间切换时不丢失上下文。
要为对象设置标签,请选择该对象,并点击工具栏上的
,或从上下文菜单中选择 标记。 然后在打开的对话框中指定文本标签。
浏览快照
要导航至与某个对象对应的函数或变量,请选择该对象,并点击工具栏上的
,或从上下文菜单中选择 编辑源代码。 如果按钮和菜单项处于禁用状态,表示 GoLand 未找到任何与所选对象对应的函数或变量。
如果找到多个函数或变量,GoLand 会将它们显示在建议列表中。
为了帮助您从包含关系角度分析对象并聚焦对象之间的链接,GoLand 允许您从 占用空间最大的对象 或 摘要 选项卡,或 出现位置 视图中的某个对象跳转至 包含关系 选项卡中的同一对象。
为实现此操作,请选择对象并从上下文菜单中选择 在主树中导航。
搜索快照
在 包含关系 选项卡中,点击工具栏上的
。
在打开的 V8 堆搜索 对话框中,指定搜索模式和要搜索的范围。 可用的搜索范围包括:
所有位置: 选中此复选框以在所有范围中搜索。 选中此复选框后,将禁用所有其他搜索类型。
链接名称: 选中此复选框以在调用 C++ runtime 时 V8 创建的对象名称中进行搜索。
在 V8 堆 工具窗口中,链接名称标记有字符
%%<link name>。类名: 选中此复选框以在函数构造器中搜索。
文本字符串: 选中此复选框以在对象内容中执行文本搜索。
快照对象 ID: 选中此复选框以在对象的唯一标识符中进行搜索。 V8 在对象创建时为其分配此格式的唯一标识符,并保留至对象销毁。 这意味着您可以在同一会话中拍摄的多个快照中查找并比较相同的对象。
在 V8 堆 工具窗口中,对象 ID 使用字符
@@<object id>进行标记。标记: 选中此复选框以在您使用 包含关系 选项卡工具栏上的
手动设置的标签中进行搜索。
搜索结果显示在 详细信息 面板的一个单独 Occurrences of '<search pattern>' 视图中。 要按您指定的搜索范围对搜索结果进行分组显示,请点击工具栏上的 按类型分组 切换按钮。
下次打开对话框时,将显示上次搜索中使用的设置。