2010-12-30 8 views
3

JVMを起動するときに "com.sun.management.jmxremote"システムプロパティを設定すると、jconsoleまたはvisualvmを実行して、そのローカルmBeanServerに接続できます。私は彼らがやっていることと同じことをしたいが、方法を理解することはできない。別のローカルプロセスでmBeanServerに接続する方法は?

ローカルに実行されているJVMを識別するために使用できるサービスURLはありますか?

特定のポートにjmxmpまたはrmiリスナーを設定し、そのポートに接続することでこれを行うことができますが、ポートを管理して、ポートはどのjvmに行きます(同じサーバー上で複数のjvmsを実行します)。

答えて

1

Attach APIが必要です。同じホスト上で実行中の[Attach API capable] JVMを見つけ出し、それぞれのメタデータを返し、JMXConnectorを有効にします。これは基本的にJConsoleを起動したときに表示され、接続メニューには、JMXコマンドラインの特殊なディレクティブで起動されなかったJava 1.6+インスタンスも含めて、実行中のJVMが表示されます。

//ニコラス

+0

添付APIは、JVMのハンドルを取得しますが、そのJVMのmBeanServerは取得しません。 attach APIのjavadocは、この呼び出しを使用してリモートでエージェントをロードする例を示しています。 –

+0

右。 JREのビルドを管理エージェント(/jre/lib/management-agent.jar)にロードし、リスニングポート(vm.loadAgent(エージェント、 "com.sun.management.jmxremote.port = 5000"など)を指定する場合は、 )、JMX Remoting APIを使用してポート5000上のMBeanServerに接続することができます。ポートアクセスなしでJVM内のMBeanServerにアクセスする方法を探していたら......わかりません.... FIFOベースのプロトコルなどを開発することができます。 – Nicholas

+0

私はポートアクセスなしで接続しようとしていませんでした...私はちょうど使用するポートを指定する必要はありませんでした。ポートを指定しない場合(つまり、vm.loadAgent(エージェント、 "com.sun.management.jmxremote")を呼び出す場合)、jvmはランダムな上位ポートを選択します。その後、vm.getAgentProperties()。get( "com.sun.management.jmxremote.localConnectorAddress")を呼び出して、mBeanServerに接続するためのURLを取得できます。 おかげさまでニコラスに感謝します。 Scott Greenman familysearch.org –

7

投稿とディスカッションのおかげでニコラスとスコットに感謝します。この情報といくつかの試行錯誤に基づいてこれをまとめることができました。

他の人と共有すると、同じ脚の仕事をする必要はありません。これはJVMに接続し、そのメモリ使用量を取得します。

import com.sun.tools.attach.VirtualMachine; 
import com.sun.tools.attach.VirtualMachineDescriptor; 
import com.sun.tools.attach.spi.AttachProvider; 

import javax.management.MBeanServerConnection; 
import javax.management.ObjectName; 
import javax.management.openmbean.CompositeData; 
import javax.management.remote.JMXConnector; 
import javax.management.remote.JMXConnectorFactory; 
import javax.management.remote.JMXServiceURL; 

public class AttachFun { 

    public static void main(String[] args) throws Exception { 
     final AttachProvider attachProvider = AttachProvider.providers().get(0); 

     VirtualMachineDescriptor descriptor = null; 
     for (VirtualMachineDescriptor virtualMachineDescriptor : attachProvider.listVirtualMachines()) { 
      if (pickThisOne(virtualMachineDescriptor)) { 
       descriptor = virtualMachineDescriptor; 
       break; 
      } 
     } 

     if (descriptor == null) throw new RuntimeException("You didn't pick one"); 

     final VirtualMachine virtualMachine = attachProvider.attachVirtualMachine(descriptor); 
     virtualMachine.loadAgent("/System/Library/Frameworks/JavaVM.framework/Home/lib/management-agent.jar", "com.sun.management.jmxremote"); 
     final Object portObject = virtualMachine.getAgentProperties().get("com.sun.management.jmxremote.localConnectorAddress"); 

     final JMXServiceURL target = new JMXServiceURL(portObject + ""); 
     final JMXConnector connector = JMXConnectorFactory.connect(target); 
     final MBeanServerConnection remote = connector.getMBeanServerConnection(); 

     final ObjectName memory = new ObjectName("java.lang:type=Memory"); 
     CompositeData cd = (CompositeData) remote.getAttribute(memory, "HeapMemoryUsage"); 

     final Long used = (Long) cd.get("used"); 
     System.out.println(used); 

    } 

    private static boolean pickThisOne(VirtualMachineDescriptor virtualMachineDescriptor) { 
     // TODO 
     return false; 
    } 
} 
+3

サンプルがいいですし、ここからも同様の詳細な例が見つかりました:http://blog.fastconnect.fr/?p=385 – ozhan

+1

JDK 8では、ロードするのがはるかに簡単になりましたエージェントとローカルアドレスを取得します。 'virtualMachine.startLocalManagementAgent'メソッドを使うべきです。 –

関連する問題