从附加代理或使用 com.sun.tools.attach.* 启动 JavaFlightRecorder;

问题描述

是否可以构建自定义代理(或重用现有代理)以在 HotSpot VM 中启用 JFR 功能?。

我的计划是构建简单的代理加载器,它使用 com.sun.tools.attach.* 包附加到 VM 并加载自定义代理。

我没有故意使用 jcmd 或其他 JDK 工具,因为我无法控制环境,因为应用程序在容器中运行,我无法控制 JRE/JDK 和 ABI for jcmd(因此我无法复制部分JDK 只是为了运行命令)。

我知道代理几乎可以做任何事情,并且由于 jcmd 是用 Java 编写的,并且它能够即时启动 FlightRecording(我认为是通过一些 JMX),那么它也应该可以通过 Java 代理,但我找不到相关文档

任何线索都会有所帮助。谢谢

解决方法

Dynamic Attach API (com.sun.tools.attach) 不适用于 JRE 8,因为它需要 tools.jarlibattach.so,它们包含在 JDK 中,但不包含在 JRE 中。

jattach 是一个用 C 编写的小型独立实用程序;它为 JRE 提供动态附加功能,可以代替 jcmd 使用:

jattach <pid> jcmd "JFR.start ..."

如果您更喜欢 Java API,则可以使用 ByteBuddyAgent。它还提供不依赖于 com.sun.tools.attach 的动态附加功能。

try (VirtualMachine.ForHotSpot.Connection conn =
             VirtualMachine.ForHotSpot.Connection.ForJnaPosixSocket.Factory
                     .withDefaultTemporaryFolder(30,100,TimeUnit.MILLISECONDS)
                     .connect(pid)) {
    conn.execute("1","jcmd","JFR.start",null,null);
}