我正在使用附加 API 在运行时加载 JVMTI 代理。我想在我的程序完成后卸载 JVMTI 代理,而不终止加载代理的 JVM。根据此文档,无法从附加 API 执行此操作。是否有任何其他方法可以强制代理通过 Java API 或从 JVMTI 代理中卸载自身?
问问题
2390 次
2 回答
6
JVMTI规范说卸载(没有 JVM 终止)是可能的,但是依赖于平台并且超出了规范的范围。
于 2011-06-05T09:59:24.107 回答
0
您必须以编程方式加载 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();
在这里查看文档
之后,您必须使用与 default 不同的 classLoad :
您必须将系统属性“java.system.class.loader”设置为目标 JVM 的自定义类加载器的名称。
在这里查看文档
“Java 的内置类加载器总是在加载之前检查一个类是否已经加载。因此,使用 Java 的内置类加载器无法重新加载该类。要重新加载一个类,您必须实现自己的 ClassLoader 子类。”
在您的情况下,您必须实现具有 ClassLoader.getSystemClassLoader() 的 ClassLoader 具有父级。
“即使使用 ClassLoader 的自定义子类,您也面临挑战。每个加载的类都需要链接。这是使用 ClassLoader.resolve() 方法完成的。此方法是最终的,因此不能在 ClassLoader 子类中覆盖。解决() 方法将不允许任何给定的 ClassLoader 实例链接同一个类两次。因此,每次要重新加载类时,都必须使用 ClassLoader 子类的新实例。这并非不可能,但在设计类时必须知道重新加载。”
请参阅动态类重新加载
于 2011-06-06T16:23:41.233 回答