如何在不停止JVM的情况下将Javaagent添加到JVM?

我希望在不停止应用程序的情况下分析Java应用程序。 我可以在应用程序运行时以某种方式添加Javaagent吗?

应该可以根据java.lang.instrument包的文档。

VM启动后启动代理

实现可以提供在VM启动之后的某个时间启动代理的机制。 有关如何启动它的详细信息是特定于实现的,但通常应用程序已经启动并且其主要方法已被调用。 如果实施支持在VM启动后启动代理,则以下情况适用:

1.代理JAR的清单必须包含属性Agent-Class。 此属性的值是代理类的名称。
2.代理类必须实现公共静态agentmain方法。
3.系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR文件添加到系统类路径的机制。

但我从未尝试过 : – |

请参阅程序启动后启动Java代理 。

它链接到http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ ,在“运行时动态加载javaagent”下提供了工作示例:

public static void loadAgent() throws Exception { String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName(); String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@')); VirtualMachine vm = VirtualMachine.attach(pid); vm.loadAgent(jarFilePath, ""); vm.detach(); } 

请注意,Java 9要求-Djdk.attach.allowAttachSelf=true才能在JVM启动参数中出现。

您可以使用ea-agent-loader

使用它在运行时加载代理将如下所示:

 public class HelloAgentWorld { public static class HelloAgent { public static void agentmain(String agentArgs, Instrumentation inst) { System.out.println(agentArgs); System.out.println("Hi from the agent!"); System.out.println("I've got instrumentation!: " + inst); } } public static void main(String[] args) { AgentLoader.loadAgentClass(HelloAgent.class.getName(), "Hello!"); } } 

这里有一个库,它通过注入检测来在运行时初始化aspectj和spring-aspects: https : //github.com/subes/invesdwin-instrument

您可以将它用作更精细的样本。