アプリケーションを停止せずに Java アプリケーションをプロファイリングしたいと考えています。アプリケーションの実行中に何らかの形で Javaagent を追加できますか?
4 に答える
プログラム開始後の Java エージェントの開始を参照してください。
http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/にリンクしており、「実行時の javaagent の動的読み込み」の下に実際の例が示されています。
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();
}
Java 9 では-Djdk.attach.allowAttachSelf=true
、JVM 起動引数の間に存在する必要があることに注意してください。
ea-agent-loaderを使用できます
実行時にエージェントをロードすると、次のようになります。
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!");
}
}
java.lang.instrumentパッケージ のドキュメントに従って可能になるはずです。
VM起動後のエージェントの起動
実装は、VMの起動後にエージェントを起動するメカニズムを提供する場合があります。これがどのように開始されるかに関する詳細は実装固有ですが、通常、アプリケーションはすでに開始されており、そのメインメソッドはすでに呼び出されています。VMの起動後に実装がエージェントの起動をサポートする場合、以下が適用されます。
1.エージェントJARのマニフェストには、属性Agent-Classが含まれている必要があります。この属性の値は、エージェントクラスの名前です。
2.エージェントクラスは、publicstaticagentmainメソッドを実装する必要があります。
3.システムクラスローダー(ClassLoader.getSystemClassLoader)は、エージェントJARファイルをシステムクラスパスに追加するメカニズムをサポートする必要があります。
しかし、私はそれを試したことがありません:-|
ここでは、インストルメンテーションを挿入することにより、実行時にspectjとspring-aspectsを初期化するライブラリ: https://github.com/subes/invesdwin-instrument
より精巧なサンプルとして使用できます。