JProfiler帮助文档

分析 JVM

要对 JVM 进行分析,必须将 JProfiler 的 profiling agent 加载到 JVM 中。这可以通过两种不同的方式进行:在启动脚本中指定 -agentpath VM 参数,或者使用 attach API 将 agent 加载到已在运行的 JVM 中。

JProfiler 支持这两种模式。添加 VM 参数是推荐的分析方式,集成向导、IDE 插件以及从 JProfiler 内部启动 JVM 的会话 (session)配置都使用这种方式。Attach 既支持本地操作,也支持通过 SSH 远程进行。

-agentpath VM 参数

了解加载 profiling agent 的 VM 参数是如何构成的会很有帮助。-agentpath 是 JVM 提供的通用 VM 参数,用于加载任何使用 JVMTI 接口的本地库 (library)。因为 profiling 接口 JVMTI 是一个本地接口,所以 profiling agent 必须是一个本地库 (library)。这意味着您只能在明确支持的平台上进行分析。32 位和 64 位 JVM 也需要不同的本地库 (library)。另一方面,Java agent 则通过 -javaagent VM 参数加载,并且只能访问有限的功能集。

在 -agentpath: 之后追加本地库 (library)的完整路径名。还有一个等效的参数 -agentlib:,使用该参数时只需指定特定于平台的库 (library)名称,但随后必须确保该库 (library)包含在库路径 (library path)中。在库 (library)路径之后,可以添加一个等号,并向 agent 传递以逗号分隔的选项。例如,在 Linux 上,整个参数可能如下所示:

-agentpath:/opt/jprofiler16/bin/linux-x64/libjprofilerti.so=port=8849,nowait

第一个等号将路径名与参数分开,第二个等号是参数 port=8849 的一部分。这个常用参数定义了 profiling agent 监听来自 JProfiler GUI 连接的端口。8849 实际上是默认端口,因此也可以省略该参数。不过,如果要在同一台机器上分析多个 JVM,则必须分配不同的端口。IDE 插件和本地启动的会话 (session)会自动分配该端口,而对于集成向导,则必须显式选择端口。

第二个参数 nowait 告知 profiling agent 不要在启动时阻塞 JVM 并等待 JProfiler GUI 连接。启动时阻塞是默认行为,因为 profiling agent 不是通过命令行参数接收其配置文件设置 (profiling setting),而是从 JProfiler GUI 或配置文件中接收。命令行参数仅用于引导 profiling agent,指示其如何启动并传递调试标志。

在某些情况下,需要在启动时指定配置文件设置 (profiling setting),并且可能需要进行一些手动操作来实现这一点。

默认情况下,JProfiler agent 将通信 socket 绑定到回环接口 (loopback interface)。您可以添加选项 address=[IP address] 以选择特定接口,或添加 address=0.0.0.0 将通信 socket 绑定到所有可用的网络接口。如果您想从 Docker 容器 (container)中发布 profiling 端口,这可能是必需的。

本地启动的会话 (session)

就像 IDE 中的“运行配置 (Run configurations)”一样,您可以直接在 JProfiler 中配置本地启动的会话 (session)。您只需指定类路径 (classpath)、主类 (main class)、工作目录、VM 参数和实参,JProfiler 就会为您启动会话 (session)。JProfiler 自带的所有演示会话 (session)都是本地启动的会话 (session)。

一种特殊的启动模式是“Web Start”,您在其中选择 JNLP 文件的 URL,JProfiler 将启动一个 JVM 来对其进行分析。该功能支持 OpenWebStart,不支持 Java 9 之前 Oracle JRE 中的旧版 WebStart。

通过从主菜单中调用 会话 (Session)→转换向导 (Conversion Wizards),可以使用转换向导将本地启动的会话 (session)转换为独立会话 (session)。将应用程序会话转换为远程会话 (Convert Application Session to Remote)仅创建一个启动脚本并将 -agentpath VM 参数插入到 Java 调用中。将应用程序会话转换为离线会话 (Convert Application Session to Offline)为离线分析创建一个启动脚本,这意味着配置在启动时加载,不需要 JProfiler GUI。将应用程序会话转换为重新分发会话 (Convert Application Session to Redistributed Session)执行相同的操作,但在其旁边创建一个包含 profiling agent 以及配置文件的目录 jprofiler_redist,以便您可以将其发送到未安装 JProfiler 的其他机器上。

如果您自己开发被分析 (profiled)的应用程序,请考虑使用 IDE 集成而不是启动的会话 (session)。这将更加方便,并为您提供更好的源代码导航。如果您不是自己开发该应用程序,但已经有启动脚本,请考虑使用远程集成向导。它将告诉您必须添加到 Java 调用中的确切 VM 参数。

集成向导

JProfiler 的集成向导支持许多知名的第三方容器 (container),这些容器带有可以通过编程方式修改以包含附加 VM 参数的启动脚本或配置文件。对于某些产品,可以生成通过参数或环境变量传递 VM 参数的启动脚本。

在所有情况下,您都必须定位第三方产品中的某些特定文件,以便 JProfiler 具有执行其修改所需的上下文。一些通用向导仅会就启用分析所需执行的操作向您提供说明。

每个集成向导的第一步都是选择在本地机器还是远程机器上进行分析。对于本地机器,您需要提供的信息更少,因为 JProfiler 已经知道平台、JProfiler 安装位置及其配置文件所在位置。

一个重要的决定是上面讨论的“启动模式 (startup mode)”。默认情况下,配置文件设置 (profiling setting)在启动时从 JProfiler UI 传输,但您也可以告知 profiling agent 让 JVM 立即启动。在后一种情况下,一旦 JProfiler GUI 连接,就可以应用配置文件设置 (profiling setting)。

但是,您也可以指定包含配置文件设置 (profiling setting)的配置文件,这样效率要高得多。这是在配置同步 (Config synchronization)步骤中完成的。在这种情况下,主要问题是每次在本地编辑配置文件设置 (profiling setting)时,都必须将配置文件与远程端同步。最优雅的方法是在远程地址 (Remote address)步骤中通过 SSH 连接到远程机器,然后配置文件可以通过 SSH 自动传输。

在集成向导结束时,将创建一个会话 (session),该会话启动分析,并且(在非通用情况下)还会启动第三方产品,例如应用服务器。

外部启动脚本由会话 (session)配置对话框的应用程序设置 (Application settings)选项卡上的执行启动命令 (Execute start command)和执行停止命令 (Execute stop command)选项处理,并且可以通过选中打开带 URL 的浏览器 (Open browser with URL)复选框来显示 URL。这也是您可以更改远程机器地址和配置同步选项的地方。

集成向导均可处理被分析 (profiled)的 JVM 在远程机器上运行的情况。但是,当必须修改配置文件或启动脚本时,您必须将其复制到本地机器并将修改后的版本传输回远程机器。直接在远程机器上运行命令行工具 jpintegrate 并让其就地执行修改可能会更方便。 jpintegrate 需要完整安装 JProfiler,并且具有与 JProfiler GUI 相同的 JRE 要求。

启动远程分析会话 (session)发生错误时,请参阅排错指南,了解解决该问题可以采取的步骤清单。

IDE 集成

分析应用程序最方便的方法是通过 IDE 集成。如果您通常在开发期间从 IDE 启动应用程序,则 IDE 已经拥有所有必需的信息,JProfiler 插件只需添加用于分析的 VM 参数,在必要时启动 JProfiler,并将被分析 (profiled)的 JVM 连接到 JProfiler 主窗口。

所有 IDE 集成都包含在 JProfiler 安装目录的 integrations 目录中。原则上,可以使用相应 IDE 中的插件安装机制手动安装该目录中的归档文件。但是,安装 IDE 集成的首选方式是从主菜单调用 会话 (Session)→IDE 集成 (IDE integrations)。

来自 IDE 的 Profiling 会话 (session)在 JProfiler 中不会获得其专属的会话 (session)条目,因为无法从 JProfiler GUI 启动此类会话 (session)。根据 IDE 中的设置,配置文件设置 (profiling setting)按项目或按运行配置进行持久化保存。

连接到 IDE 时,JProfiler 会在工具栏中显示一个窗口切换器,方便快速跳回 IDE 中的关联窗口。所有的显示源代码 (Show Source)操作现在都直接在 IDE 中显示源码,而不是在 JProfiler 的内置源码查看器中显示。

IDE 集成将在后续章节中详细讨论。

适用于人工智能 (AI) Agent 的 MCP 服务器

JProfiler 包含一个 MCP 服务器,允许诸如 Claude Code、Antigravity 或 Junie 等人工智能 (AI)编码 Agent 使用 JProfiler 的分析和分析功能。人工智能 (AI) Agent 可以启动并分析 Java 进程,attach 到本地运行的 JVM 或 Docker 容器 (container)中的 JVM,创建堆转储 (heap dump)并分析现有的快照。MCP 集成可以通过主菜单中的 会话 (Session)→AI Agent 集成 (AI Agent Integrations) 进行设置。

Attach 模式

您不一定必须事先决定要分析某个 JVM。借助 JProfiler 中的 attach 功能,您可以选择正在运行的 JVM 并即时加载 profiling agent。虽然 attach 模式非常方便,但您应该注意它的一些缺点:

  • 您必须从正在运行的 JVM 列表中识别出要分析的 JVM。如果同一台机器上运行着大量 JVM,这有时会很棘手。
  • 存在额外的开销,因为可能必须重新定义许多类以添加 instrumentation。
  • JProfiler 中的某些功能在 attach 模式下不可用。这主要是因为 JVMTI 的某些功能只能在 JVM 初始化时开启,而在 JVM 生命周期的后续阶段不可用。
  • 某些功能需要在很大比例的类中进行 instrumentation。在加载类时进行 instrumentation 成本较低,而在类已加载后添加 instrumentation 成本较高。当您使用 attach 模式时,此类功能默认处于禁用状态。
  • Attach 功能支持 OpenJDK JVM、版本为 6 或更高版本的 Oracle JVM、最新的 OpenJ9 JVM(8u281+、11.0.11+ 或 Java 17+)或基于此类版本的 IBM JVM。绝不能为 JVM 指定 VM 参数 -XX:+PerfDisableSharedMem 和 -XX:+DisableAttachMechanism。

JProfiler 启动中心中的 快速附加 选项卡列出了所有可被分析的 JVM。列表条目的背景颜色指示是否已加载 profiling agent、当前是否已连接 JProfiler GUI,或者是否已配置离线分析。

启动 profiling 会话 (session)时,可以在会话设置对话框中配置配置文件设置 (profiling setting)。当您重复分析同一个进程时,您不想一次又一次地重新输入相同的配置,因此在关闭通过快速附加功能创建的会话 (session)时,可以保存持久会话 (session)。下次要分析此进程时,请从 启动会话 (Start Session) 选项卡而不是 快速附加 选项卡启动保存的会话 (session)。您仍然必须选择正在运行的 JVM,但配置文件设置 (profiling setting)与您之前配置的相同。

Attach 到本地服务

JVM 中的 attach API 要求调用进程与要 attach 的进程以相同的用户运行,因此 JProfiler 显示的 JVM 列表仅限于当前用户。由不同用户启动的进程大多是服务。在 Windows、Linux 和基于 Unix 的平台上,attach 到服务的方式有所不同。

在 Windows 上,attach 对话框有一个显示服务 (Show Services)按钮,用于列出本地运行的所有服务。JProfiler 启动桥接可执行文件,以便能够 attach 到这些进程,无论它们以何种用户运行。

在 Linux 上,JProfiler 支持通过大多数 Linux 发行版都包含的 PolicyKit 直接在 UI 中切换用户。通过点击 attach 对话框中的切换用户 (Switch User),您可以输入不同的用户名并通过系统密码对话框进行身份验证。

在包括 macOS 在内的基于 Unix 的平台上,您可以根据您的 Unix 变体或 Linux 发行版,使用 su 或 sudo 以其他用户身份执行命令行工具 jpenable。在 macOS 和基于 Debian 的 Linux 发行版(如 Ubuntu)上,使用 sudo。

使用 sudo,请调用

sudo -u userName jpenable
使用 su,所需的命令行是
su userName -c jpenable

jpenable 将让您选择 JVM,并告诉您 profiling agent 正在监听的端口。之后,您可以从 JProfiler UI 使用本地会话 (session)进行连接,也可以使用直接连接 jpenable 所提供端口的 SSH 连接。

Attach 到远程机器上的 JVM

Profiling 要求最高的设置是远程分析——JProfiler GUI 在本地机器上运行,而被分析 (profiled)的 JVM 在另一台机器上运行。对于将 -agentpath VM 参数传递给被分析 (profiled) JVM 的设置,您必须在远程机器上安装 JProfiler 并在本地机器上设置远程会话 (session)。借助 JProfiler 中的远程 attach 功能,无需进行此类修改。您只需要 SSH 凭据即可登录远程机器。

SSH 连接使 JProfiler 能够上传“安装 JProfiler”帮助主题中讨论的 agent 包,并在远程机器上执行包含的命令行工具。您不需要在本地机器上设置 SSH,JProfiler 自带其专有实现。在最直接的设置中,您只需定义主机、用户名和身份验证。

通过 SSH 连接,JProfiler 可以自动发现正在运行的 JVM,或者连接到 profiling agent 已在监听的特定端口。对于后一种情况,您可以按照上述方法在远程机器上使用 jpenable 或 jpintegrate,并准备专门的 JVM 进行分析。然后,可以将 SSH 远程 attach 配置为直接连接到已配置的 profiling 端口。

自动发现将列出远程机器上以 SSH 登录用户身份启动的所有 JVM。在大多数情况下,这不会是启动您要分析的服务的用户。因为启动服务的用户通常不允许进行 SSH 连接,所以 JProfiler 添加了一个切换用户 (Switch User)超链接,允许您使用 sudo 或 su 切换到该用户。

在复杂的网络拓扑中,有时无法直接连接到远程机器。在这种情况下,您可以告知 JProfiler 在 GUI 中通过多跳 SSH 隧道进行连接。在 SSH 隧道的末端,您可以进行一次直接网络连接,通常连接到“127.0.0.1”。

对于其他身份验证机制,您可以使用 OpenSSH 隧道模式。输入主机名的方式与使用 OpenSSH 可执行文件时在命令行中输入的方式相同。这也可以是 OpenSSH 配置文件中配置的别名。除主机名外,还可以选择指定端口和用户名。在 Windows 上,仅支持 Microsoft 内置的 OpenSSH 客户端。

SSH 选项文本字段接收您在命令行中指定的 OpenSSH 可执行文件的任意附加参数。当您遵循教程提供的说明时(例如如何通过 AWS session manager 建立 SSH 隧道连接),这特别有用。

HPROF 快照只能针对以 SSH 登录用户身份启动的 JVM 拍摄。这是因为 HPROF 快照需要一个中间文件,该文件是以启动 JVM 的用户的访问权限写入的。出于安全原因,无法将文件权限转移给 SSH 登录用户进行下载。完整的 profiling 会话 (session)不存在此类限制。

Attach 到在 Docker 容器 (container)中运行的 JVM

Docker 容器 (container)通常没有安装 SSH 服务器,虽然可以在 Docker 容器 (container)中使用 jpenable,但除非您在 Dockerfile 中指定了 profiling 端口,否则从外部无法访问该端口。

在 JProfiler 中,您可以通过在快速附加对话框中选择 Docker 容器 (container),attach 到在 Windows 或 macOS 中的本地 Docker Desktop 安装中运行的 JVM。默认情况下,JProfiler 会自动检测 docker 可执行文件的路径。或者,您可以在常规设置对话框的“外部程序 (External Programs)”选项卡上进行配置。

选择容器 (container)后,将显示 Docker 容器 (container)内部运行的所有 JVM。当您选择一个 JVM 时,JProfiler 将使用 Docker 命令在所选容器 (container)中自动安装 profiling agent,为 JVM 的分析做好准备,并将 profiling 协议通过隧道转发到外部。

对于远程 Docker 安装,您可以使用 SSH 远程 attach 功能,然后在远程机器上选择 Docker 容器 (container)。如果登录用户不在 docker 用户组中,您可以先按上述方式切换用户。

通过远程 attach 对话框中的选择容器 (Select Container)超链接,您可以选择正在运行的 Docker 容器 (container)并显示其中运行的所有 JVM。

Attach 到在 Kubernetes 集群上运行的 JVM

要分析在 Kubernetes 集群上运行的 JVM,JProfiler 使用 kubectl 命令行工具,既用于发现 Pod 和容器 (container),也用于连接到容器 (container)、列出其 JVM 并最终连接到所选的 JVM。

kubectl 命令行工具可以在您的本地计算机上可用,也可以在您具有 SSH 访问权限的远程机器上可用。JProfiler 直接支持这两种场景。对于本地安装,JProfiler 将尝试自动检测 kubectl 的路径,但您可以在常规设置对话框的“外部程序 (External Programs)”选项卡上配置显式路径。

JProfiler 在具有三个级别的树中列出所有检测到的容器 (container)。顶部是包含带有检测到 Pod 的子节点的命名空间节点。叶节点是容器 (container)本身,必须选择其中一个才能继续选择正在运行的 JVM。

kubectl 可能需要额外的命令行选项进行身份验证,以便能够连接到 Kubernetes 集群。这些选项可以在容器 (container)选择对话框的顶部输入。由于这些选项可能是敏感信息,因此仅当您显式选中在重启时记住它们的复选框时,它们才会保存到磁盘。取消选中此复选框将立即清除所有先前保存的信息。

设置正在运行的 JVM 的显示名称

在 JVM 选择表中,显示的进程名称是被分析 (profiled) JVM 的主类及其实参。对于由 exe4j 或 install4j 生成的启动程序,将显示可执行文件的名称。

如果您希望自己设置显示的名称(例如因为您有多个具有相同主类且否则无法区分的进程),则可以设置 VM 参数 -Djprofiler.displayName=[name]。如果名称包含空格,请使用单引号:-Djprofiler.displayName='My name with spaces',并在必要时用双引号将整个 VM 参数引起来。除了 -Djprofiler.displayName 之外,JProfiler 还可以识别 -Dvisualvm.display.name。