Desidero profilare un'applicazione Java senza arrestare l'applicazione. Posso aggiungere un Javaagent in qualche modo mentre l'applicazione è in esecuzione?Come posso aggiungere Javaagent a una JVM senza arrestare la JVM?
risposta
Dovrebbe essere possibile secondo la documentazione del pacchetto java.lang.instrument.
di agenti che iniziano dopo il VM Startup
Un'implementazione possono fornire un meccanismo per iniziare agenti qualche dopo che il VM è iniziata. I dettagli di come inizializzati sono specifici dell'implementazione ma in genere l'applicazione ha già avviato e il suo metodo principale ha già già richiamato. Nei casi in cui l'applicazione supporta la di partenza di agenti dopo la VM ha iniziato vale quanto segue:
1. manifesta del JAR agente deve contenere l'attributo Agent-Class. Il valore di questo attributo è il nome della classe dell'agente .
2. La classe dell'agente deve implementare un metodo agent statico pubblico .
3. Il caricatore di classi di sistema (ClassLoader.getSystemClassLoader) deve supportare un meccanismo per aggiungere un file JAR dell'agente al percorso di classe del sistema.
ma non ho mai provato: - |
"potrebbe fornire" :-(Sembra divertente :) :) –
Vedere Starting a Java agent after program start.
si collega a http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ che in "carico dinamico di un javaagent in fase di esecuzione" fornisce esempio funzionante:
public static void loadAgent() throws Exception {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgent(jarFilePath, "");
vm.detach();
}
Nota che Java 9 prevede -Djdk.attach.allowAttachSelf=true
ad essere presente tra gli argomenti di avvio JVM.
Ecco una libreria che inizializza aspectj e primavera-aspetti in fase di runtime strumentazione iniettando: https://github.com/subes/invesdwin-instrument
è possibile utilizzarlo come un campione di più elaborato.
È possibile utilizzare ea-agent-loader
Con esso il caricamento di un agente in fase di esecuzione sarà simile:
public class HelloAgentWorld
{
public static class HelloAgent
{
public static void agentmain(String agentArgs, Instrumentation inst)
{
System.out.println(agentArgs);
System.out.println("Hi from the agent!");
System.out.println("I've got instrumentation!: " + inst);
}
}
public static void main(String[] args)
{
AgentLoader.loadAgentClass(HelloAgent.class.getName(), "Hello!");
}
}
Ho controllato il caricatore di ea-agent, che sembra abbastanza buono. Purtroppo non funziona per me: https://stackoverflow.com/questions/48678557/how-to-start-aspectj-loadtime-weaver-agent-without-restarting-jvm-how-to-start e qui https://github.com/electronicarts/ea-agent-loader/issues/9 – cilap
I tempi avrei voluto connettere il debugger nella produzione ... – omerkudat
@omerkudat :) Ouchy. Quindi eseguilo con l'opzione debugger, non vedrai alcun reale svantaggio delle prestazioni, ma i debugger possono causare perdite – bestsss
Quindi l'opzione debugger mi consente di aggiungere un javaagent in fase di runtime? – Zubair