在运行时卸载JVMTI代理?

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

JVMTI 规范说卸载(没有JVM终止)是可能的,但是依赖于平台并超出了规范的范围。

您必须以编程方式加载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这里

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

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

看到doc这里

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

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

“即使使用ClassLoader的自定义子类,您也会遇到挑战。每个加载的类都需要链接。这是使用ClassLoader.resolve()方法完成的。此方法是最终的,因此无法在ClassLoader子类中重写。 ()方法不允许任何给定的ClassLoader实例两次链接同一个类。因此,每次你想重新加载一个类时,你必须使用你的ClassLoader子类的一个新实例。这不是不可能的,但必须知道何时为类设计重装“。

请参阅动态类重新加载