java 如何在不停止 JVM 的情况下向 JVM 添加 Javaagent?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4817670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I add a Javaagent to a JVM without stopping the JVM?
提问by Yazz.com
I wish to profile a Java application without stopping the application. Can I add a Javaagent somehow while the application is running?
我希望在不停止应用程序的情况下分析 Java 应用程序。我可以在应用程序运行时以某种方式添加 Javaagent 吗?
采纳答案by user85421
It should be possible according the documentation of the java.lang.instrumentpackage.
根据java.lang.instrument包的文档应该是可能的。
Starting Agents After VM Startup
An implementation may provide a mechanism to start agents sometime after the the VM has started. The details as to how this is initiated are implementation specific but typically the application has already started and its main method has already been invoked. In cases where an implementation supports the starting of agents after the VM has started the following applies:
1.The manifest of the agent JAR must contain the attribute Agent-Class. The value of this attribute is the name of the agent class.
2. The agent class must implement a public static agentmain method.
3. The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path.
VM 启动后启动代理
一个实现可以提供一种机制来在 VM 启动后的某个时间启动代理。关于如何启动的细节是特定于实现的,但通常应用程序已经启动并且它的主要方法已经被调用。如果实现支持在 VM 启动后启动代理,则以下适用:
1.代理JAR的manifest必须包含属性Agent-Class。该属性的值是代理类的名称。
2. 代理类必须实现公共静态agentmain 方法。
3. 系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR文件添加到系统类路径的机制。
but I have never tried it:-|
但我从未尝试过:-|
回答by Vadzim
See Starting a Java agent after program start.
请参阅程序启动后启动 Java 代理。
It links to http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/that under "Dynamic loading of a javaagent at runtime" provides working example:
它链接到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();
}
Note that Java 9 requires -Djdk.attach.allowAttachSelf=true
to be present among JVM startup arguments.
请注意,Java 9 需要-Djdk.attach.allowAttachSelf=true
出现在 JVM 启动参数中。
回答by Daniel Sperry
You can use ea-agent-loader
您可以使用ea-agent-loader
With it loading an agent in runtime will look like:
使用它在运行时加载代理将如下所示:
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!");
}
}
回答by subes
Here a library that initializes aspectj and spring-aspects at runtime by injecting instrumentation: https://github.com/subes/invesdwin-instrument
这是一个通过注入检测在运行时初始化 aspectj 和 spring-aspects 的库:https: //github.com/subes/invesdwin-instrument
You can use it as a more elaborate sample.
您可以将其用作更精细的示例。