VirtualMachine
VirtualMachine (가상 머신 연결과 에이전트 로드)
현재 자바 가상 머신이 연결(attach)한 대상 자바 가상 머신을 나타내는 추상 클래스입니다. 연결된 쪽을 가리켜 **대상 가상 머신(target VM)**이라고 부르기도 해요.
본문
관리 콘솔이나 프로파일러 같은 도구가 이 VirtualMachine을 사용해 대상 VM에 에이전트를 로드합니다. 예를 들어 자바로 작성한 프로파일러가 실행 중인 애플리케이션에 붙어서 프로파일링 에이전트를 로드하는 식이에요.
VirtualMachine은 대상 VM을 식별하는 식별자를 attach 메서드에 넘겨 얻습니다. 식별자는 구현에 따라 다르지만, 각 VM이 자기 운영체제 프로세스로 실행되는 환경에서는 보통 프로세스 식별자(pid)입니다. 또는 list 메서드가 반환한 VirtualMachineDescriptor 목록에서 가져온 설명자를 attach에 넘겨 인스턴스를 얻을 수도 있어요.
public abstract class VirtualMachine extends Object
인스턴스를 얻은 뒤에는 loadAgent, loadAgentLibrary, loadAgentPath 메서드로 대상 VM에 에이전트를 로드합니다. loadAgent는 자바 언어로 작성되어 JAR 파일로 배포된 에이전트를 로드할 때 쓰고, loadAgentLibrary/loadAgentPath는 동적 라이브러리나 VM에 정적 링크되어 JVM Tools Interface를 사용하는 에이전트를 로드할 때 씁니다.
에이전트 로드 외에도 대상 VM의 시스템 프로퍼티를 읽어올 수 있습니다. java.home, os.name, os.arch 같은 값을 이용해 로드할 에이전트 경로를 만들 때 유용해요. 이 클래스는 여러 동시 스레드에서 안전하게 사용할 수 있습니다. Java 1.6부터 존재합니다.
protected VirtualMachine(AttachProvider provider, String id)
// attach to target VM
VirtualMachine vm = VirtualMachine.attach("2177");
// start management agent
Properties props = new Properties();
props.put("com.sun.management.jmxremote.port", "5000");
vm.startManagementAgent(props);
// detach
vm.detach();
위 예시에서는 프로세스 식별자 2177로 식별되는 VM에 연결한 뒤, JMX 관리 에이전트를 시작하고 마지막에 연결을 해제합니다.
list() / attach()
public static List<VirtualMachineDescriptor> list()
public static VirtualMachine attach(String id) throws AttachNotSupportedException, IOException
public static VirtualMachine attach(VirtualMachineDescriptor vmd) throws AttachNotSupportedException, IOException
list()는 설치된 모든 attach provider의 listVirtualMachines 결과를 합쳐 VM 설명자 목록을 반환합니다. attach(String id)는 각 provider의 attachVirtualMachine을 차례로 호출하며, 성공하는 provider가 나오면 그 VM을 반환해요. 모든 provider가 AttachNotSupportedException을 던지면 이 메서드도 같은 예외를 던집니다.
detach()
public abstract void detach() throws IOException
가상 머신과의 연결을 해제합니다. 해제 후 그 VM에 연산을 호출하면 IOException이 발생해요. 이미 해제된 상태라면 아무 효과가 없습니다.
loadAgentPublic()
public abstract void loadAgent(String agent, String options)
throws AgentLoadException, AgentInitializationException, IOException
public void loadAgent(String agent)
자바 에이전트를 로드합니다. agent는 대상 VM 파일 시스템의 JAR 파일 경로이며, java.lang.instrument 명세대로 JAR의 Agent-Class 속성에 지정된 에이전트 클래스의 agentmain 메서드가 호출됩니다.
loadAgentLibrary() / loadAgentPath()
public abstract void loadAgentLibrary(String agentLibrary, String options)
public abstract void loadAgentPath(String agentPath, String options)
JVM TI 에이전트 라이브러리를 로드합니다. loadAgentLibrary는 라이브러리 이름을 받아 대상 VM에서 OS 특정 파일 이름으로 확장하고, loadAgentPath는 전체 경로를 받아 확장 없이 그대로 사용해요. 대상 VM은 에이전트의 Agent_OnAttach 함수(정적 링크 에이전트 'L'은 Agent_OnAttach_L)를 호출합니다. 이 함수가 오류를 반환하면 AgentInitializationException이 던져지고, 반환 값은 예외의 returnValue()로 얻을 수 있어요. 각 메서드는 options를 생략하는 편의 오버로드도 제공합니다.
getSystemProperties() / getAgentProperties()
public abstract Properties getSystemProperties() throws IOException
public abstract Properties getAgentProperties() throws IOException
각각 대상 VM의 시스템 프로퍼티와 에이전트 프로퍼티를 읽어옵니다. 키나 값이 String이 아닌 프로퍼티는 생략돼요.
startManagementAgent() / startLocalManagementAgent()
public abstract void startManagementAgent(Properties agentProperties) throws IOException
public abstract String startLocalManagementAgent() throws IOException
대상 VM에 JMX 관리 에이전트를 시작합니다. startManagementAgent는 com.sun.management.jmxremote.port 같은 설정이 필요하고, startLocalManagementAgent는 로컬 커넥터의 서비스 주소 문자열을 반환합니다.
provider() / id()
public final AttachProvider provider()
public final String id()
각각 이 VM을 만든 attach provider와 이 VM의 식별자를 반환합니다.
equals() / hashCode()
public boolean equals(Object ob)
public int hashCode()
두 VirtualMachine이 같은 provider를 참조하고 식별자가 같다면 서로 같다고 판단합니다.