我发现Java attach API可以加载javaagent,如下代码所示:
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import java.util.List;
public class ListVM{
public static void main(String[] args){
List<VirtualMachineDescriptor> vmList = VirtualMachine.list();
for(VirtualMachineDescriptor vm : vmList){
System.out.println("name: " + vm.displayName() + " id :" + vm.id());
try{
VirtualMachine vm0 = VirtualMachine.attach(vm.id());
// load agent, agnet class's agentmain will be invoked.
vm0.loadAgent("/root/tmp/ChinaAgent.jar");
System.out.println("Load agent done.");
vm0.detach();
}catch(Exception e) {
System.out.println("exception : " + e.getMessage());
}
}
}
}
语句:vm0.loadAgent("/root/tmp/ChinaAgent.jar");
加载代理jar文件。
但代理商的代码只会运行一次,
所以我猜Agent jar只加载一次,这意味着Jvm会阻止多次加载代理。
这是真的吗?为什么?希望可以有一些代码来证明它!
谢谢!答案 0 :(得分:2)
当您致电loadAgent
时,代理商jar会运行一次。调用JAR清单中agentmain
属性指定的代理类的Agent-Class
方法。
该类实际上已加载一次,除非您已经对卸载类进行了一些优化。因此,如果您在同一个jar上多次调用loadAgent,则不会重新加载类,但可能会多次调用Agent_OnAttach
(agentmain)。
实际上它是特定于平台的,取决于JVM的实现。
loadAgent
方法调用loadAgentLibrary
,调用特定于平台的Agent_OnAttach
参考文献:
jdk\src\windows\native\sun\tools\attach\WindowsVirtualMachine.c
文件