JProfiler帮助文档Download

记录数据


Profiler 的主要目的是从各种来源记录运行时数据,这些数据对于解决常见问题非常有用。此任务的主要问题是运行中的 JVM 以惊人的速度生成此类数据。如果 Profiler 始终记录所有类型的数据,它将产生不可接受的开销或迅速耗尽所有可用内存。此外,您通常希望围绕特定用例记录数据,而不查看任何不相关的活动。

这就是 JProfiler 提供细粒度机制来控制您实际感兴趣的信息记录的原因。

标量值和遥测

从 Profiler 的角度来看,数据中最不成问题的形式是标量值,例如活动线程的数量或打开的 JDBC 连接的数量。JProfiler 可以以固定的宏观频率(通常为每秒一次)对这些值进行采样,并向您展示随时间的演变。在 JProfiler 中,显示此类数据的视图称为 遥测。大多数遥测始终被记录,因为测量的开销和内存消耗很小。如果长时间记录数据,较旧的数据点会被合并,以便内存消耗不会随时间线性增长。

还有参数化的遥测,例如每个类的实例数量。额外的维度使永久的时间顺序记录不可持续。您可以告诉 JProfiler 记录选定类的实例计数的遥测,但不是每个类的。

继续前面的例子,JProfiler 能够向您展示所有类的实例计数,但没有时间顺序信息。这是“所有对象”视图,它将每个类显示为表中的一行。更新视图的频率低于每秒一次,并且可能会根据测量造成的开销自动调整。确定所有类的实例计数相对昂贵,并且对象越多,所需时间越长。这就是为什么“所有对象”不会自动更新,您需要手动创建所有对象的新转储。

一些测量捕获枚举类值,例如线程当前的执行状态。这种类型的测量可以显示为彩色时间线,并且消耗的内存比数值遥测少得多。在线程状态的情况下,“线程历史”视图显示 JVM 中所有线程的时间线。就像数值遥测一样,较旧的值被合并并变得更加粗粒度,以减少内存消耗。

分配记录

如果您对在某个时间间隔内分配的实例计数感兴趣,JProfiler 必须跟踪所有分配。与“所有对象”视图相反,JProfiler 可以遍历堆中的所有对象以按需获取信息,跟踪单个分配需要为每个对象分配执行额外的代码。这使得它成为一种非常昂贵的测量,可能会显著改变被分析应用程序的运行时特性,例如性能热点,特别是如果您分配了许多对象。这就是为什么分配记录必须明确启动和停止的原因。

具有相关记录的视图最初显示一个带有记录按钮的空白页面。工具栏中也可以找到相同的记录按钮。

分配记录不仅记录分配的实例数量,还记录分配的堆栈跟踪。为每个分配记录保留堆栈跟踪在内存中会产生过多的开销,因此 JProfiler 将记录的堆栈跟踪累积到树中。这也有一个优势,您可以更轻松地解释数据。但是,时间顺序方面丢失,无法从数据中提取某些时间范围。

内存分析

分配记录只能测量对象的分配位置,并且没有关于对象之间引用的信息。任何需要引用的内存分析,例如解决内存泄漏,都是在堆漫游器中完成的。堆漫游器会对整个堆进行快照并进行分析。这是一种侵入性操作,会暂停 JVM(可能会持续很长时间),并且需要大量内存。

一种更轻量级的操作是在开始用例之前标记堆上的所有对象,以便您可以在稍后进行堆快照时找到所有新分配的对象。

JVM 具有一个特殊的触发器,用于将整个堆转储到一个以旧 HPROF Profiler 代理命名的文件中。这与分析接口无关,也不受其约束。因此,HPROF 堆转储速度更快,使用的资源更少。缺点是当在堆漫游器中查看堆快照时,您将没有与 JVM 的实时连接,并且某些功能不可用。

方法调用记录

测量方法调用所需的时间是一种可选记录,就像分配记录一样。方法调用被累积到树中,并且有各种视图从不同的角度显示记录的数据,例如调用图。在 JProfiler 中,这种类型的数据记录称为“CPU 记录”。

在特定情况下,查看方法调用的时间顺序可能很有用,尤其是在涉及多个线程时。对于这些特殊情况,JProfiler 提供了“调用跟踪器”视图。该视图具有与更通用的 CPU 记录无关的单独记录类型。请注意,调用跟踪器生成的数据过多,无法用于解决性能问题,它仅用于一种特殊形式的调试。

调用跟踪器依赖于 CPU 记录,并在必要时自动打开。

另一个具有自己记录的专用视图是“复杂性分析”。它仅测量选定方法的执行时间,并且不需要启用 CPU 记录。其附加数据轴是方法调用的算法复杂性的数值,您可以使用脚本计算该值。通过这种方式,您可以测量方法的执行时间如何依赖于其参数。

Monitor 记录

要分析线程等待或阻塞的原因,必须记录相应的事件。此类事件的速率差异很大。对于多线程程序,其中线程经常协调任务或共享公共资源,可能会有大量此类事件。这就是为什么默认情况下不记录此类时间顺序数据的原因。

当您打开 Monitor 记录时,“锁定历史图”和“Monitor 历史”视图将开始显示数据。

为了消除噪音并减少内存消耗,非常短的事件不会被记录。视图设置为您提供了调整这些阈值的可能性。

探针记录

探针显示 JVM 中的高级子系统,例如 JDBC 调用或文件操作。默认情况下,不记录任何探针,您可以分别为每个探针切换记录。某些探针会增加很少或没有开销,而某些探针会根据您的应用程序正在执行的操作以及探针的配置产生大量数据。

就像分配记录和方法调用记录一样,探针数据被累积,时间顺序信息被丢弃,除了时间线和遥测。然而,大多数探针还有一个“事件”视图,允许您检查单个事件。这会增加潜在的大量开销,并具有单独的记录操作。该记录操作的状态是持久的,因此当您切换探针记录时,如果您之前已打开它,相关的事件记录也会被切换。

JDBC 探针具有第三个记录操作,用于记录 JDBC 连接泄漏。查找连接泄漏的相关开销仅在您实际尝试调查此类问题时才会产生。就像事件记录操作一样,泄漏记录操作的选择状态是持久的。

记录配置文件

在许多情况下,您希望通过单击一次来启动或停止各种记录。逐一访问所有相应的视图并切换记录按钮是不切实际的。这就是 JProfiler 具有记录配置文件的原因。可以通过单击工具栏中的 开始记录 按钮来创建记录配置文件。

记录配置文件定义可以原子激活的特定记录组合。JProfiler 尝试向您提供有关所选记录所产生的开销的粗略印象,并尝试阻止有问题的组合。特别是,分配记录和 CPU 记录不能很好地结合在一起,因为分配记录会显著扭曲 CPU 数据的时间。

您可以在会话运行时随时激活记录配置文件。记录配置文件不是累加的,它们会停止所有不包含在记录配置文件中的记录。使用 停止记录 按钮,您可以停止所有记录,无论它们是如何激活的。要检查当前激活的记录,请将鼠标悬停在状态栏中的记录标签上。

在开始分析时也可以直接激活记录配置文件。“会话启动”对话框具有一个 初始记录配置文件 下拉菜单。默认情况下,未选择任何记录配置文件,但如果您需要 JVM 启动阶段的数据,这是配置所需记录的地方。

使用触发器记录

有时您希望在特定条件发生时开始记录。JProfiler 具有一个 定义触发器的系统,该系统执行一系列操作。可用的触发器操作还包括对活动记录的更改。

例如,您可能希望仅在执行特定方法时开始记录。在这种情况下,您可以转到会话设置对话框,激活 触发器设置 选项卡,并为该方法定义一个方法触发器。对于操作配置,您可以使用多种不同的记录操作。

“开始记录”操作控制这些记录,没有任何参数。通常,当您停止并重新启动记录时,所有先前记录的数据都会被清除。对于“CPU 数据”和“分配数据”记录,您还可以选择保留先前的数据并继续跨多个时间间隔累积。

可以通过在调用树中使用上下文菜单中的“添加方法触发器”操作方便地添加方法触发器。如果您在同一会话中已经有一个方法触发器,您可以选择将方法拦截添加到现有触发器。

默认情况下,触发器在 JVM 启动进行分析时处于活动状态。有两种方法可以在启动时禁用触发器:您可以在触发器配置中单独禁用它们,或者在会话启动对话框中取消选择 启动时启用触发器 复选框。在实时会话期间,您可以通过从菜单中选择 分析→(启用|禁用) 触发器 或单击状态栏中的  触发器记录状态图标来启用或禁用所有触发器。

有时,您需要同时切换触发器组的激活。这可以通过将相同的组 ID 分配给感兴趣的触发器并从菜单中调用 分析→启用触发器组 来实现。

使用 jpcontroller 记录

JProfiler 具有一个命令行可执行文件,用于控制任何已被分析的 JVM 中的记录。jpcontroller 要求 JProfiler MBean 已发布,否则它将无法连接到被分析的 JVM。只有在分析代理已经接收到分析设置的情况下才会出现这种情况。如果没有分析设置,代理将不知道要准确记录什么。

必须满足以下条件之一:

  • 您已经使用 JProfiler GUI 连接到 JVM
  • 被分析的 JVM 是使用包含 nowaitconfig 参数的 -agentpath VM 参数启动的。在集成向导中,这对应于 立即启动 模式和 启动时应用配置 选项在 配置同步 步骤中。
  • JVM 已使用 jpenable 可执行文件准备进行分析,并指定了 -offline 参数。有关更多信息,请参见 jpenable -help 的输出。

具体来说,如果被分析的 JVM 仅使用 nowait 标志启动,则 jpcontroller 将无法工作。在集成向导中,连接 JProfiler GUI 时应用配置 选项在 配置同步 步骤中将配置此类参数。有关更多信息,请参见 有关在启动时设置分析设置的帮助主题

jpcontroller 为您提供了一个循环的多级菜单,用于所有记录及其参数。您还可以使用它保存快照。

以编程方式启动记录

另一种启动记录的方法是通过 API。在被分析的 VM 中,您可以调用 com.jprofiler.api.controller.Controller 类以编程方式启动和停止记录。有关更多信息以及如何获取包含控制器类的工件,请参见 离线分析章节

如果您想在不同的 JVM 中控制记录,您可以访问被分析的 JVM 中使用的相同 MBean,该 MBean 也由 jpcontroller 使用。设置 MBean 的编程使用相当复杂,需要相当多的步骤,因此 JProfiler 附带了一个您可以重用的示例。查看文件 api/samples/mbean/src/MBeanProgrammaticAccessExample.java。它在另一个被分析的 JVM 中记录 CPU 数据 5 秒钟,并将快照保存到磁盘。