【问题标题】:How to unload Java Agents jars after adding them dynamically in code? Java instrumentation在代码中动态添加 Java 代理 jar 后如何卸载它们? Java 检测
【发布时间】:2013-08-06 02:54:38
【问题描述】:

我创建了一个 java 代理 jar 文件(在命令行上完美运行)。 接下来,我想将此代理附加到 j2ee 服务器中正在运行的 JVM。 所以我使用了代码:

public static void loadAgent() {   

    System.out.println("dynamically loading javaagent");
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
    int p = nameOfRunningVM.indexOf('@');
    String pid = nameOfRunningVM.substring(0, p);

    try {
        VirtualMachine vm = VirtualMachine.attach(pid);
        String jarFilePath = vm.getSystemProperties().getProperty("java.home")+File.separator+"lib"+File.separator+"test-agent-7.jar";            
        vm.loadAgent(jarFilePath, "");
        vm.detach();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

编辑:这现在可以工作了,我可以看到 Transformer 被调用了。 我还可以移除变压器并能够调试变压器。

我的问题是:

  • 完成后如何卸载此 java 代理 jar?
  • 是关闭/重启 JVM 的唯一方法吗?
  • 如果 jar 留在内存中会有什么影响吗?

【问题讨论】:

  • @Tal 你的问题解决了吗?
  • 不幸的是没有...代理 jar 保持加载..

标签: java instrumentation agent javaagents


【解决方案1】:

嗯,有几件事需要考虑:

如果加载代理,则加载类。只要相关的类加载器在 Java VM 的内存中,相关的类就会保持加载状态。我认为你不能轻易地防止/规避。但这应该只是您通过加载代理所产生的一小部分内存开销。

一些研究表明,代理将由 SystemClassLoader 加载,因此无法卸载这些类。

VM 启动后启动代理

一个实现可能会提供一种机制来在某个时候启动代理 虚拟机启动后。有关如何启动的详细信息 是特定于实现的,但通常应用程序已经 已启动,并且它的 main 方法已被调用。在这种情况下 一个实现支持在 VM 启动后启动代理 开始以下适用: 代理 JAR 的清单必须包含属性 Agent-Class。该属性的值是代理的名称 班级。 代理类必须实现公共静态 agentmain 方法。 系统类加载器 (ClassLoader.getSystemClassLoader) 必须支持将代理 JAR 文件添加到系统类路径的机制。 Link to source

但是,您可以影响的是代理正在做什么。

您要关闭该代理吗?提供关闭方法。

如果你想从外部停止代理,这个代理可以提供一个 JMXBean 来关闭代理。

然后,此方法可以从 Instrumentation 接口中删除转换器或停止代理在 Java VM 中执行的任何其他操作(释放所持有的引用/资源,以便对对象进行垃圾收集,诸如此类)。

如果不更具体地说明您想要实现的目标,很难给出更合适的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-25
    • 2012-04-08
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2011-02-15
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多