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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:09:36  来源:igfitidea点击:

How can I add a Javaagent to a JVM without stopping the JVM?

javajvmjavaagents

提问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=trueto 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.

您可以将其用作更精细的示例。