JProfiler帮助文档Download

JFR 快照中的视图


除了 JFR 事件浏览器,JProfiler 使用了一些可用于完整分析会话的视图,并用 JFR 数据填充它们。这是可能的,因为 JFR 收集了内存分配和方法执行的数据。主要的限制是记录速率较低,因此获取足够的数据以查看问题热点可能需要很长时间。

遥测

除了“记录对象遥测”外,完整分析会话中的所有遥测也可以在 JFR 快照中使用,但显示的数据有一些限制。内存遥测不显示 GC 特定的池,线程遥测不显示线程状态的线程计数,记录的吞吐量遥测显示大小而不是对象计数,并且不显示正在释放的对象。

下表显示了各种遥测使用的事件类型,以及它们是否在“默认”和“配置文件”模板中启用。

遥测事件类型在配置文件中启用
内存jdk.GCHeapSummary, jdk.MetaspaceSummary全部
记录的吞吐量jdk.ObjectAllocationSample, jdk.ObjectAllocationInNewTLAB, jdk.ObjectAllocationOutsideTLAB仅配置文件
GC 活动jdk.GarbageCollection全部
jdk.ClassLoadingStatistics全部
线程jdk.JavaThreadStatistics全部
CPU 负载jdk.CPULoad全部

内存视图

在“内存”部分,使用了两种不同的事件类型来填充视图数据。“活动对象”视图向您展示了在完整垃圾回收后仍然保留在堆上的所有类和实例计数的统计表示。此数据仅在启用了 jdk.ObjectCount 事件时可用,而默认的 JFR 模板中没有启用该事件,因为它带来了显著的开销。您还可以在高级 JFR 配置中通过“垃圾收集器”下拉菜单切换此设置。在 Java 17 之前,此下拉菜单标记为“内存分析”。

如果在快照中多次记录了 jdk.ObjectCount 事件,视图将向您显示 第一次和最后一次出现jdk.ObjectCount 事件之间的差异。通过这种方式,您可以了解在记录时间内数字如何变化,并可能提供一些内存泄漏的指示。如果这些时间与快照记录的开始和结束点不一致,则在遥测视图中添加相应的书签。仅包括总对象大小超过固定阈值(通常为堆的 1%)的类。

对于任何严肃的调查,请考虑使用 完整分析会话 或拍摄 HPROF 快照

“记录对象”视图以及分配视图向您展示了自 Java 16 以来的 jdk.ObjectAllocationSample 事件的数据,以及早期 Java 版本中的 jdk.ObjectAllocationInNewTLABjdk.ObjectAllocationOutsideTLAB 事件。高级 UI 中的“分配分析”下拉菜单还提供了一种启用这些事件类型的方法。

与“活动对象”视图相反,它们仅显示在记录活动时分配的对象。分配由 JFR 采样,但大小报告为 总分配大小的估计值。由于这种差异,这些视图报告的大小与样本计数乘以平均实例大小不对应。否则,这些视图具有与 完整分析会话中的内存视图 类似的功能。

CPU 视图

“CPU 视图”包括调用树、热点视图以及调用图。数据基于默认情况下在标准 JFR 模板中记录的 jdk.ExecutionSample 事件中的“可运行”线程状态。然而,采样率默认设置为 20 毫秒,这对应于 JFR 高级 UI 中“方法采样”设置的“正常”选项。考虑到 JFR 仅采样非常少量的随机线程,因此获取足够的数据以使热点足够突出可能需要很长时间。如有必要,请考虑降低 jdk.ExecutionSample 的周期。请记住,这可能导致非常大的快照大小,因为 JFR 不累积数据。

由于线程是偶尔采样的,因此不可能像在完整分析会话中那样估计实际执行时间。调用树和热点视图中显示的是 事件计数,而不是时间。这类似于 异步采样,它具有相同的缺点。其他 JFR 线程状态为“等待”、“阻塞”和“Socket 和文件 I/O”,仍然测量时间。由于这种差异,线程状态选择器中不可用“所有线程状态”模式。

另一个考虑因素是,非可运行线程状态是从具有可配置最小持续时间阈值的事件计算得出的,这些阈值显示在线程状态选择器旁边的工具提示中。这些线程状态的实际总时间可能大得多。用于组装线程状态的事件类型表如下所示:

线程状态事件类型
可运行jdk.ExecutionSample
等待jdk.JavaMonitorWait, jdk.ThreadSleep, jdk.ThreadPark
阻塞jdk.JavaMonitorEnter
Socket 和文件 I/Ojdk.SocketRead, jdk.SocketWrite, jdk.FileRead, jdk.FileWrite

视图的功能在 CPU 视图帮助主题 中进行了说明。请注意,完整分析会话的许多功能在 JFR 上下文中不可用。

线程和监视器视图

从时间顺序方法采样数据中,可以计算线程历史视图,包括显示等待和阻塞时间的堆栈跟踪的工具提示。

线程转储是 JFR 和 JProfiler 中的一个功能,并在同一视图中显示。在这种情况下,事件浏览器不是替代品,因为它无法显示 jdk.ThreadDump 事件的线程转储列的结构化内容。在线程转储视图中,您还可以 比较不同的线程转储

jdk.JavaMonitorWaitjdk.ThreadSleepjdk.ThreadPark 事件中,JProfiler 计算出类似于 完整分析会话 的监视器历史,只是没有阻塞线程的信息。如果您需要这些信息来解决问题,请切换到完整分析会话。这也意味着完整分析会话中的锁定图形在 JFR 快照中不可用。显示等待事件汇总信息的监视器使用统计信息存在,并且仅显示等待时间。

探针

完整分析会话中的一些 JVM 探针在 JFR 快照中具有等效的数据源。与事件浏览器相比,它们的主要优势在于它们结合了多个相关的事件类型。下表显示了可用探针及其用作数据源的事件类型。

探针事件类型在配置文件中启用
Socketsjdk.SocketRead, jdk.SocketWrite全部
文件jdk.FileRead, jdk.FileWrite全部
jdk.ClassLoad, jdk.ClassUnload, jdk.ClassDefine
异常jdk.JavaErrorThrow, jdk.JavaExceptionThrow错误在两者中,异常在无
垃圾收集器 jdk.GarbageCollection, jdk.GCPhasePause, jdk.YoungGarbageCollection, jdk.OldGarbageCollection, jdk.GCReferenceStatistics, jdk.GCPhasePauseLevel<n>, jdk.GCHeapSummary, jdk.MetaspaceSummary, jdk.GCHeapConfiguration, jdk.GCConfiguration, jdk.YoungGenerationConfiguration, jdk.GCSurvivorConfiguration, jdk.GCTLABConfiguration 全部

类加载在高级 JFR UI 中有一个单独的复选框,可以打开所有三个类加载事件。

每个探针显示多个视图。与事件浏览器相比,重点是聚合数据而不是单个事件。这也是 JProfiler 中的探针在概念上与 JFR 数据收集的不同之处。

除了垃圾收集器探针外,所有探针都有以下视图:调用树和热点视图允许您选择单个线程或线程组以及聚合级别。默认情况下,显示所有线程,并且聚合级别设置为“方法”。

遥测视图显示来自记录数据的一种或多种遥测,并提供一个概览页面,显示所有遥测。可以通过单击遥测名称打开完整的遥测。通过沿时间轴拖动,您可以在事件视图中选择相应的事件。

事件视图类似于 JFR 浏览器中的视图。然而,它显示了与底层 JFR 事件相对应的多种事件类型,并提供了类型选择器。单选和多选的过滤和堆栈跟踪显示与事件浏览器中的处理方式相同。此外,还有时间和内存测量的直方图视图,您可以通过沿水平轴拖动来选择范围。

垃圾收集器视图是特殊的,因为完整分析会话可以在 Java 17 或更高版本的分析会话中显示完全相同的信息。当 JVM 探针类别中的垃圾收集器探针被记录时,使用 JFR 流来获取必要的数据。有关更多信息,请参阅 垃圾收集器分析 章节。