2010-12-30 3 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

Right. 관리 에이전트 (/jre/lib/management-agent.jar)에 JRE 빌드를로드하고 수신 대기 포트 (예 : vm.loadAgent (agent, "com.sun.management.jmxremote.port = 5000");), JMX Remoting API를 사용하여 포트 5000의 MBeanServer에 연결할 수 있습니다. 포트 액세스없이 JVM에서 MBeanServer에 액세스하는 방법을 찾고 있다면 ...... 확실하지 않습니다 .... 당신은 FIFO 기반 프로토콜 또는 무엇인가를 개발할 수있을 것입니다. – Nicholas

+0

포트 액세스없이 연결하려고하지 않았습니다 ... 사용할 포트를 지정하고 싶지 않았습니다. 포트를 지정하지 않으면 (즉, vm.loadAgent (agent, "com.sun.management.jmxremote")를 호출하면) jvm이 임의의 상위 포트를 선택합니다. 그런 다음 vm.getAgentProperties(). get ("com.sun.management.jmxremote.localConnectorAddress")를 호출하여 mBeanServer에 연결할 URL을 가져올 수 있습니다. 도움을 주신 Nicholas에게 감사드립니다. 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' 메소드를 사용해야합니다. –

관련 문제