【问题标题】:Unloading a JVMTI agent at runtime?在运行时卸载 JVMTI 代理?
【发布时间】:2011-09-01 18:19:28
【问题描述】:

我正在使用附加 API 在运行时加载 JVMTI 代理。我想在我的程序完成时卸载 JVMTI 代理,而不终止加载代理的 JVM。根据this documentation,无法从附加 API 执行此操作。是否有任何其他方法可以强制代理通过 Java API 或从 JVMTI 代理中卸载自身?

【问题讨论】:

  • 这并不意味着是一个正确的答案,而只是一个建议。 JNI 也有类似的问题(我想卸载一个模块)。我发现的最佳解决方案很简单:生成一个新的 JVM 实例来处理模块,等待它终止,然后当它终止时,模块显然会被卸载。我敢打赌,在挣扎了一段时间之后,你会结束这样做。我建议你跳过“斗争”阶段:P

标签: java jvmti


【解决方案1】:

JVMTI spec says 卸载(没有 JVM 终止)是可能的,但取决于平台并且超出规范的范围。

【讨论】:

    【解决方案2】:

    您必须以编程方式加载 JVMTI 代理:

    // attach to target VM
    VirtualMachine vm = VirtualMachine.attach("2177");
    
    // get system properties in target VM
    Properties props = vm.getSystemProperties();
    
    // construct path to management agent
    String home = props.getProperty("java.home");
    String agent = home + File.separator + "lib" + File.separator 
        + "your-agent-example.jar";
    
    // load agent into target VM
    vm.loadAgent(agent, "com.sun.management.jmxremote.port=5000");
    
    // detach
    vm.detach();
    

    doc here

    之后,您必须使用与默认值不同的 classLoad:

    您必须将系统属性“java.system.class.loader”设置为目标 JVM 的自定义类加载器的名称。

    doc here

    "Java 的内置类加载器总是在加载一个类之前检查它是否已经加载。 因此,使用 Java 的内置类加载器无法重新加载该类。 要重新加载一个类,您必须实现自己的 ClassLoader 子类。”

    在您的情况下,您必须实现具有 ClassLoader.getSystemClassLoader() 的 ClassLoader 具有父级。

    “即使使用 ClassLoader 的自定义子类,您也面临挑战。 每个加载的类都需要链接。 这是使用 ClassLoader.resolve() 方法完成的。 这个方法是最终的,因此不能在您的 ClassLoader 子类中被覆盖。 resolve() 方法不允许任何给定的 ClassLoader 实例链接同一个类两次。 因此,每次要重新加载类时,都必须使用 ClassLoader 子类的新实例。 这并非不可能,但在设计类重载时必须知道。”

    Dynamic Class Reloading

    【讨论】:

    • 这对作为本机代码的 JVMTI 代理没有帮助。从 JVM 分离不会导致 JVMTI 代理被卸载。
    • 我不这么说。代码示例只是在这里展示如何加载代理。从 JVM 中卸载代理与卸载类的问题相同。唯一的解决方案是使用您自己的类加载器。
    • 如果您查看附加文档,它清楚地指出 loadAgent 用于加载用 Java 编写的代理,而 loadAgentLibrary 和 loadAgentPath 用于加载本机代码的 JVMTI 代理。由于 JVMTI 代理是本机代码而不是 Java 类,因此您对类加载器的讨论​​不适用。见download.oracle.com/javase/6/docs/jdk/api/attach/spec/…
    • 我同意了,我的解决方案仅适用于 java 代理。
    猜你喜欢
    • 2013-06-26
    • 2015-09-29
    • 2013-06-18
    • 1970-01-01
    • 2019-06-14
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    相关资源
    最近更新 更多