난이도 : 중급
Cathy Kegley, 소프트웨어 엔지니어, IBM Greg Roberts, 스태프 소프트웨어 엔지니어, IBM
2008 년 3 월 11 일
자바 SE 6(Java™ Platform, Standard Edition 6)은 성능에 초점을 맞춰 응용 프로그램을 모니터링, 감시하고 공통적인 문제를 진단하기 위해 확장된 도구들을 제공합니다. 이 기사에서는 자바 SE 플랫폼의 모니터링과 관리에 대한 기본적인 사항들을 소개하고, 자바 SE 6에서 보강된 사항들에 대한 상세한 정보를 제공합니다.
자바 SE 6은 응용 프로그램을 관리, 모니터링하고 일반적인 문제점을 진단하는 확장된 도구들을 제공한다. 개선된 사항은 다음과 같다.
- 모니터링 및 관리(Monitoring and management) API 향상
- 개선된 그래픽 모니터링 도구인 JConsole에 대한 공식 지원
- 강화된 자바 가상 머신(JVM) 도구
이 기사는 자바 SE 플랫폼의 모니터링과 관리에 대한 기본적인 사항들을 소개하고, 최신 버전에서 보강된 사항들에 대해 상세한 정보를 제공한다. 또한 자바 SE 6 플랫폼에서 사용할 수 있는 진단 및 문제 해결 도구들에 대해 설명한다.
이 기사를 통해 이전 버전의 자바 SE에서 소개된 모니터링 및 관리 기능을 확실히 이해하게 될 것이다. 참고자료를 통해 자세한 배경 정보를 볼 수 있다.
모니터링 및 관리 API
자바 SE 5는 java.lang.management 패키지에 플랫폼 MBean 또는 MXBean이라는 9개의 MBean을 정의한다(참고자료). 각 MXBean은 JVM의 단일 기능 영역을 감싸고 있다. 자바 SE 5부터 JVM은 플랫폼 MBean 서버라고 부르는 MBean 서버를 내장하고 있다. MBean은 이 저장소 안에 존재하고 관리된다. 표 1에 자바 플랫폼에 포함된 9개의 MXBean을 요약했다. 표 1. 플랫폼 MBeans
관리 인터페이스 |
관리되는 자원 |
ClassLoadingMXBean |
클래스 로더 |
CompilationMXBean |
컴파일러 |
MemoryMXBean |
메모리 |
ThreadMXBean |
스레드 |
RuntimeMXBean |
런타임 |
OperatingSystemMXBean |
운영체제 |
GarbageCollectorMXBean |
가비지 컬렉터 |
MemoryManagerMXBean |
메모리 관리자 |
MemoryPoolMXBean |
메모리 풀 |
어떤 응용 프로그램이라도 원하는 빈의 인스턴스를 얻고 절적한 메서드를 호출해 JVM이 제공하는 플랫폼 MBean을 사용할 수 있다. 로컬 또는 원격 JVM의 동작을 모니터링하고 정보를 얻기 위해 MXBean을 사용할 수 있다.
플랫폼 MBean은 적재된 클래스 개수, JVM 가동시간, 메모리 소모량, 실행 중인 스레드 개수, 스레드 경쟁에 대한 통계 등의 정보에 대해 접근을 제공한다.
JVM 리소스를 모니터링하고 관리하는 두 가지 방법이 있다.
MXBean 인터페이스를 통한 직접 접근
MBeanServer 인터페이스를 통한 간접 접근
MXBean 인터페이스를 통한 직접 접근
정적인 팩토리 메서드를 통해 MXBean 인스턴스를 얻어 로컬에서 실행 중인 JVM의
MXBean 인터페이스에 직접 접근할 수 있다. ManagementFactory 클래스는 MXBean을 얻을 수 있는 정적인 팩토리 메서드를 제공한다. Listing 1은 이 팩토리를 통해 RuntimeMXBean 을 얻어 표준 속성 중 하나인 VmVendor 의 값을 얻는 방법을 보여준다. Listing 1. MXBean에 직접 접근하기
RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
// Get the standard attribute "VmVendor"
String vendor = mxbean.getVmVendor();
|
MBeanServer 인터페이스를 통한 간접 접근
플랫폼 MBeanServer 인터페이스는 원격 JVM에 연결하고 그 플랫폼에서 실행 중인 MXBean에 접근하기 위해 MXBeanServerConnection 을 사용한다. ManagementFactory 클래스의 getPlatformMBeanServer 메서드를 사용해 플랫폼 MBean 서버에 접근할 수 있다. Listing 2는 원격에서 실행 중인 JVM에서 RuntimeMXBean 을 얻고, VmVendor 속성의 값을 얻는 방법을 보여준다. Listing 2. MXBean에 간접 접근하기
MBeanServerConnection serverConn;
try {
//connect to a remote VM using JMX RMI
JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://<addr>");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
serverConn = jmxConnector.getMBeanServerConnection();
ObjectName objName = new
ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
// Get standard attribute "VmVendor"
String vendor =
(String) serverConn.getAttribute(objName, "VmVendor");
} catch (...) { }
|
참고자료에서 MXBean과 the java.lang.management API에 대한 더 자세한 정보를 볼 수 있다.
자바 SE 6에서 보강된 API
자바 SE 5는 락(lock)과 대기 조건(wait codition)에 대한 프레임워크를 제공하는 java.util.concurrent.locks 패키지를 도입했다. 이 프레임워크는 자바의 내장된 동기화 지원과는 별도로 더욱 융통성 있는 락 사용을 가능케 해 주었다.
자바 SE 6은 java.lang.management 패키지에 java.util.concurrent.locks 에 대한 지원을 추가했다. 여기에는 락에 대한 정보를 제공하는 새로운 클래스와 ThreadInfo , ThreadMXBean , OperatingSystemMXBean 에 대한 보강이 포함되었다.
자바 SE 6은 새로운 클래스 두 개를 도입했다.
LockInfo 는 락에 대한 정보를 갖고 있다.
MonitorInfo 는 LockInfo 를 상속해 객체 모니터 락에 대한 정보를 갖고 있다.
ThreadInfo 클래스는 새로운 객체들을 사용하기 위해 새 메서드 세 가지를 도입했다.
getLockInfo() 는 주어진 스레드가 차단 대기중인 LockInfo 객체를 반환한다.
getLockedMonitors() 는 주어진 스레드에 의해 현재 락된 MonitorInfo 객체를 반환한다.
getLockedSynchronizers() 는 주어진 스레드에 의해 현재 락된 소유 가능한 동기화
객체(ownable synchronizer)를 표현하는 LockInfo 객체를 반환한다.
ThreadMXBean.getThreadInfo 메서드는 자바 SE 5에서는 스레드가 획득 대기중이거나 진입 차단된 차단된 객체 모니터에 대해서만 보고했지만, 자바 SE 6부터는 획득 대기중인 스레드의 AbstractOwnableSynchronizer 를 보고하도록 보강되었다.
ThreadMXBean 인터페이스도 메서드 네 개를 추가했다.
isObjectMonitorUsageSupported() 는 가상 머신이 객체 모니터에 대한 모니터링을
지원하는지 여부를 검사한다.
isSynchronizerUsageSupported() 는 소유 가능한 동기화 객체의 사용 모니터링을
지원하는지 여부를 검사한다.
findDeadlockedThreads() 는 데드락된 스레드 ID의 배열을 반환한다. 데드락된 스레드는 다른 스레드가 객체 모니터나 동기화 객체에 진입하는 것을 차단하고 있는 스레드다.
dumpAllThreads() 는 모든 살아있는 스레드에 대한 스택 트레이스와 동기화 정보를 반환한다.
마지막으로, OperatingSystemMXBean 인터페이스에 최근 수 분 동안 시스템의 평균 부하를 반환하는 getSystemLoadAverage() 가 추가되었다.
프로그래밍 수준 지원과 더불어, 자바 SE 6은 문제를 감지하고 JVM의 자원 사용량을 모니터링하기 위한 몇 가지 진단 및 문제 해결 도구를 제공한다. 다음 두 절에서는 사용할 수 있는 진단 도구들에 설명하고 사용 예를 보여준다.
자바 모니터링 및 관리 콘솔(JConsole)
자바 SE 6은 자바 SE 5부터 도입된 모니터링 및 관리 콘솔인 JConsole에 대한 공식 지원을 포함한다. JConsole을 통해 실행 중에 다양한 JVM 통계를 모티터링할 수 있다. 이 도구는 데드락, 락 경합, 메모리 누수, 순환 스레드 등의 증상을 감지하는 데 유용하다. 이 도구는 로컬이나 원격 JVM에 연결하여 다음과 같은 정보를 모니터링할 수 있다.
- 스레드 상태(연관된 락을 포함한)
- 메모리 사용량
- 가비지 컬렉션
- 런타임 정보
- JVM 정보
다음 절에서 자바 SE 6에서 JConsole의 보강된 부분들을 설명한다. 참고자료에서 JConsole을 시작하고 사용하는 방법에 대한 추가 정보를 볼 수 있다.
Attach API 지원
자바 SE 6부터 JConsole은 새로운 Attach API를 구현하고 있다. 이 com.sun.tools.attach 와 com.sun.tools.attach.spi 두 개의 패키지로 구성되어 있으며, 대상 가상 머신에 동적으로 부착되어 대상 JVM에서 에이전트를 실행하는 응용 프로그램을 구현할 수 있다.
예전에는 JConsole로 모니터링하려면 응용 프로그램을 -Dcom.sun.management.jmxremote 옵션을 사용하여 시작해야 했지만, 더 이상 그 옵션을 사용할 필요가 없다. 동적인 부착을 통해 JConsole은 Attach API를 지원하는 어떤 응용 프로그램이라도 지원할 수 있게 되었다. JConsole은 시작하면서 호환 응용 프로그램을 자동으로 감지한다.
보강된 UI와 MBean 표현
자바 SE 6에서는 JConsole이 Windows® 운영체제나 GNOME 데스크톱 등의 실행 중인 플랫폼과 비슷한 룩앤필을 갖도록 수정했다. 이 기사에서 이후부터 볼 스크린샷은 윈도우 XP에서 찍은 것으로 이전 버전과 달라진 UI 기능들을 보여준다.
일단 시작해 응용 프로그램과 연결되면, JConsole은 각각 다른 JVM 자원을 표현하는 6개의 탭으로 구성된 화면을 제공한다.
- Overview
- Memory
- Threads
- Classes
- VM Summary
- MBeans
Overview 탭은 상호 연관된 메모리 사용량, 스레드, 클래스, CPU 사용량에 대한 정보를 그래프 형식으로 표시한다. Overview 탭은 예전에는 여러 개의 탭을 전환해야 했던 관련된 정보들을 한 페이지에 표시한다. 그림 1은 예제 응용 프로그램의 Overview 탭을 보여준다. 그림 1. JConsole의 Overview 탭
Overview 탭은 VM 자원 사용 정보에 대한 4개의 그래프와 결과를 보고 싶은 시간 범위를 바꾸기 위한 선택 목록을 표시한다. 첫 번째 힙 메모리 사용량 그래프는 시간대별로 사용된 힙 메모리의 양을 메가바이트 단위로 표시한다. 이 그래프는 메모리 누수를 감지하는 데 유용하다. 응용 프로그램에 메모리 누수가 있다면 힙 메모리 사용량은 시간이 지남에 따라 꾸준히 늘어난다.
스레드 그래프는 시간대 별로 살아있는 스레드 개수를, 클래스 그래프는 적재된 클래스 개수를 표시한다. CPU 사용량 차트는 응용 프로그램 생명 주기의 다양한 지점에서의 CPU 사용량을 표시한다.
그림 2의 VM Summary 탭은 자바 SE 6에 새로 추가된 것이다. 여기에는 총 가동시간, 스레드 정보, 적재된 클래스 개수, 메모리 통계, 가비지 컬렉션, 운영체제 정보를 포함한 JVM에 대한 자세한 정보를 제공한다. 그림 2. JConsole의 VM Summary 탭
MBeans 탭은 MBean들의 동작과 속성에 더 쉽게 접근할 수 있도록 개선되었다. 플랫폼에 등록된 모든 MBean의 정보를 표시한다. 모든 플랫폼 MBean은 이 탭을 통해 접근할 수 있다. 왼쪽에 현재 실행중인 모든 MBean을 트리 구조로 표시한다. MBean을 선택하면 MBeanInfo와 설명자가 오른쪽에 표시된다(그림 3). 그림 3. JConsole의 MBean 탭
Attributes 노드를 선택하면 MBean의 모든 속성을 표시한다(그림 4). 그림 4. MBean Attributes
오른쪽에 표시된 속성과 값은 앞에서 설명한 java.lang.management 패키지의 ThreadMXBean API를 통해 접근할 수 있다는 점을 주목하자. 나열된 속성 값을 더블클릭하면 추가 정보를 얻을 수 있다. 굵게 표시된 속성값은 확장할 수 있다. 예를 들어, AllThreadIds 값을 더블클릭하면 22개 스레드의 스레드 ID를 모두 표시한다(그림 5). 그림 5. 확장된 속성 값
쓰기 가능한 속성은 파란색으로 표시되는데, 클릭한 다음 새 값을 입력해 편집할 수 있다. 예를 들어, 그림 5의 JConsole 화면에서 ThreadContentionMonitoringAvailable 속성을 이 방식으로 편집할 수 있다.
왼쪽 트리 구조에서 Operations 노드를 선택하면 MBean과 연관된 동작들을 표시한다. MBean 동작은 오른쪽에 버튼으로 표시되는데, 클릭하면 지정한 메서드를 호출한다. 그림 6은
ThreadMXBean 의 가용한 동작들을 보여준다. 그림 6. MBean Operations
핫스팟 진단 MBean
자바 SE 6부터 JConsole은 핫스팟 진단(HotSpot Diagnostic) MBean을 지원한다. 이 MBean은 즉석(on-the-spot) 동작을 수행하기 위해 이번 버전에 도입되었다. 이 API를 통해 사용자는 실행 중에 힙을 덤프하거나 다른 VM 옵션을 설정할 수 있다. MBean 탭에서 com.sun.management 노드를 확장하고 HotSpotDiagnostic 을 선택하면 핫스팟 진단 MBean에 접근할 수 있다. 그림 7에서 핫스팟 진단 MBean에서 가용한 메서드들을 볼 수 있다. Figure 7. 핫스팟 진단 MBean
JConsole 플러그인 지원
자바 SE 6부터 JConsole은 플러그인을 지원한다. JConsole과 함께 실행할 수 있는 고유한 플러그인을 만들 수 있다. 예를 들어, 응용 프로그램에 특화된 MBean에 접근해 고유의 모니터링 동작을 수행하는 탭을 JConsole의 메인 화면에 추가할 수 있다.
커스텀 JConsole 플러그인을 만들려면 com.sun.tools.jconsole.JConsolePlugin 추상 클래스를 상속해야 한다. JConsole 화면에 제대로 나타나게 하려면 메서드 두 개를 구현해야 한다.
newSwingWorker() 는 플러그인의 GUI를 갱신하는 SwingWorker 객체를 반환한다.
getTabs() 는 JConsole 창에 추가될 탭의 맵을 반환한다.
JConsole은 서비스-공급자 메커니즘을 사용해 모든 플러그인 클래스를 감지하고 적재한다. 이 때문에, 플러그인 클래스는 META-INF/services/com.sun.tools.jconsole.JConsolePlugin 파일을 포함하는 JAR 파일로 제공해야 한다. 이 파일은 한 줄에 하나씩 나열된 플러그인 클래스의 완전한 이름 목록을 포함해야 한다. 아래 명령으로 JConsole을 실행하면 새로운 플러그인 클래스를 JConsole 화면에 불러온다.
jconsole -pluginpath plugin_path
|
이 명령에서, plugin_path는 JConsole 플러그인들이 들어있는 디렉터리나 JAR 파일의 위치다. 여러 개의 경로를 지정할 수 있다.
자바 SE 6에는 JTop이라는 JConsole 플러그인이 예제로 포함되어 있다. JTop은 현재 응용 프로그램 내에서 실행중인 스레드의 CPU 사용량을 보여준다. JConsole을 JTop과 함께 실행하려면 아래 명령을 실행하면 된다.
jconsole -pluginpath JAVA_HOME/demo/management/JTop/JTop.jar
|
그림 8은 JTop 탭이 선택된 JConsole을 보여준다. 왼쪽 컬럼은 실행 중인 스레드의 이름을 표시한다. 각 스레드에 대해 CPU 사용량과 스레드 상태가 표시된다. 통계가 변하면 화면이 자동으로 갱신된다. JTop 플러그인은 CPU 점유율이 높은 스레드를 식별하는 데 유용하다. 그림 8. JConsole의 JTop 플러그인
모니터링 및 문제 해결 도구
자바 SE 6은 JConsole 외에도 몇 가지 다른 명령행 도구를 포함한다. 이 진단 도구들은 응용 프로그램을 특수한 모드로 실행할 필요 없이 아무 응용 프로그램에나 부착할 수 있다. 응용 프로그램이 의도한 대로 동작하는지를 확인하기 위한 정보를 얻을 수 있다. 이 도구들은 실험적이며 이후에 나올 자바 SE 버전에서는 지원되지 않을 수 있음을 주의하자.
모니터링 도구
자바 SE 6은 JVM의 성능 통계를 모니터링하는 데 유용한 명령행 유틸리티들을 포함하고 있다(표 2). 표 2. 모니터링 도구
도구 |
설명 |
jps |
JVM 프로세스 상태 도구 |
jstat |
JVM 통계 모니터링 도구 |
jstatd |
JVM jstat 데몬 |
jps 유틸리티는 대상 시스템의 현재 사용자에 대한 가상 머신을 나열한다. 이 유틸리티는 일반적인 자바 실행기 대신, JNI Invocation API를 통해 시작한 VM 환경에 유용하다. 이러한 환경에서는 프로세스 목록에서 자바 프로세스를 식별하는 것이 쉽지만은 않다.
jps 도구는 이 문제를 완화한다.
다음 예제는 jps 사용 예를 보여준다. 단순히 명령행에서 jps 를 입력하면, 사용자가 접근 권한을 가진 가상 머신 목록과 프로세스 ID를 나열한다(Listing 3). Listing 3. jps 유틸리티 사용하기
$ jps
16217 MyApplication
16342 jps
|
jstat 유틸리티는 JVM에 내장된 도구를 사용해 실행 중인 응용 프로그램의 성능과 자원 소모에 대한 정보를 제공한다. 이 툴은 힙 크기 및 가비지 컬렉션과 연관된 성능 이슈를 진단하는 데 유용하다.
jstatd 데몬은 JVM 생성과 종료를 모니터링하고 원격 모니터링 도구가 로컬 호스트에 실행 중인 JVM에 부착할 수 있도록 해주는 원격 메서드 호출(Remote Method Invocation, RMI) 서버 애플리케이션이다. 예를 들어, 이 데몬을 통해 jps 유틸리티는 원격 시스템의 프로세스 목록도 나열할 수 있다.
참고자료에서 이 도구들 각각에 대한 추가 문서와 사용 예를 볼 수 있다.
문제 해결 도구
자바 SE 6은 응용 프로그램이 예상치 못한 동작을 할 때 정밀한 처방을 내릴 수 있도록 도와주는 몇 가지 문제 해결 도구들도 포함하고 있다(표 3). 표 3. 문제 해결 도구
도구 |
설명 |
jinfo |
설정 정보 |
jhat |
힙 덤프 열람기 |
jmap |
메모리 맵 |
jsadebugd |
서비스 가능 여부 진단 에이전트 디버그 데몬 |
jstack |
스택 트레이스 |
jinfo 명령행 유틸리티는 실행 중인 자바 프로세스의 설정 정보나 충돌 덤프를 추출하고, 가상 머신을 시작할 때 사용한 시스템 프로퍼티나 명령행 플래그를 출력한다.
jhat 도구는 힙의 스냅샷에서 객체 위상을 열람할 수 있는 편리한 수단을 제공한다. 힙 분석 도구 (Heap Analysis Tool, HAT)를 대체하기 위해 자바 SE 6에서 도입된 이 도구는 메모리 누수를 감지하는 데 유용하다.
jmap 명령행 유틸리는 실행 중인 VM이나 코어(core) 파일에 대한 메모리 관련 통계를 출력한다. jsadebugd 데몬을 사용하면 원격 기계의 프로세스나 코어 파일을 조회할 수 있다. jmap 도구는 OutOfMemoryError 를 야기할 수 있는 finalizer의 과도한 사용을 진단하는 데 유용하다.
jsadebugd (Serviceability Agent Debug Daemon)은 자바 프로세스나 코어 파일에 부착되어 디버그 서버처럼 동작한다. 이 유틸리티는 현재 솔라리스 OS와 Linux®에서만 사용할 수 있다. 자바 RMI를 사용해 jstack , jmap , jinfo 같은 원격 클라이언트를 이 서버에 부착할 수 있다.
jstack 명령행 유틸리티는 지정한 프로세스나 코어 파일에 부착되어 VM의 내부 스레드를 포함한 가상 머신에 부착된 모든 스레드의 스택 트레이스를 출력하며, 선택적으로 네이티브 스택 프레임도 출력할 수 있다. 이 도구는 jsadebugd 데몬을 통해 원격 기계의 프로세스나 코어 파일을 조회할 수 있다. jstack 도구는 데드락을 진단하는 데 유용하다.
참고자료에서 이 도구들 각각에 대한 추가 문서와 사용 예를 볼 수 있다.
결론
자바 6 플랫폼은 자바 응용 프로그램의 성능과 메모리 문제를 효과적으로 식별하고 진단하는 것을 돕기 위해 몇 가지 VM 기구, 관리 API, 그리고 JDK 도구들을 강화했다. 이 기사는 자바 SE의 모니터링 및 관리 프레임워크에서 향상된 부분들을 설명하고, 개발자들이 사용할 수 있는 명령행 진단 유틸리티에 대해 다루었다.
자바 응용 프로그램의 평균 속도는 시간이 지남에 따라 꾸준히 증가하고 있다. 자바 SE 6이 나오면서 자바의 성능은 C나 C++에 비견할 정도가 되었다. 많은 경우에 자바 코드는 눈에 띌 정도로 빨라졌다. 그리고 여기에서 소개한 도구들을 사용해 더 나은 성능 최적화를 이룰 수 있을 것이다. 시도해보자. 예전에는 결코 알 수 없었던, 응용 프로그램의 성능을 향상시킬 수 있는 지점을 발견하게 될 것이라고 장담한다.
참고자료 교육
Caroline Gough, developerWorks, 2006년 4월): MXBean에 대한 더 자세한 정보
썬 개발자 네트워크, 2006년 8월): 자바 SE에서 공통적인 성능 문제 진단하기
이 API를 먼저 살펴보라.
소개한 모니터링 및 문제 해결 도구들에 대한 문서와 예제
토론
필자소개
|
|
|
Cathy Kegley는 IBM의 Lotus Expeditor 클라이언트 팀의 소프트웨어 엔지니어다. |
|
|
|
Greg Roberts는 IBM의 Lotus Expeditor 클라이언트 개발 팀의 스태프 소프트웨어 엔지니어다. | |