반응형

자바 SE 6의 성능 모니터링 및 진단 (한글)

자바 최신 버전에서 향상된 성능과 모니터링의 장점을 활용하기

 

 

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

 




난이도 : 중급

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는 락에 대한 정보를 갖고 있다.
  • MonitorInfoLockInfo를 상속해 객체 모니터 락에 대한 정보를 갖고 있다.

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.attachcom.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 탭
JConsole의 Overview 탭

Overview 탭은 VM 자원 사용 정보에 대한 4개의 그래프와 결과를 보고 싶은 시간 범위를 바꾸기
위한 선택 목록을 표시한다. 첫 번째 힙 메모리 사용량 그래프는 시간대별로 사용된 힙 메모리의
양을 메가바이트 단위로 표시한다. 이 그래프는 메모리 누수를 감지하는 데 유용하다.
응용 프로그램에 메모리 누수가 있다면 힙 메모리 사용량은 시간이 지남에 따라 꾸준히 늘어난다.

스레드 그래프는 시간대 별로 살아있는 스레드 개수를, 클래스 그래프는 적재된 클래스 개수를
표시한다. CPU 사용량 차트는 응용 프로그램 생명 주기의 다양한 지점에서의 CPU 사용량을
표시한다.

그림 2의 VM Summary 탭은 자바 SE 6에 새로 추가된 것이다. 여기에는 총 가동시간, 스레드 정보,
적재된 클래스 개수, 메모리 통계, 가비지 컬렉션, 운영체제 정보를 포함한 JVM에 대한 자세한
정보를 제공한다.


그림 2. JConsole의 VM Summary 탭
JConsole의 VM Summary 탭

MBeans 탭은 MBean들의 동작과 속성에 더 쉽게 접근할 수 있도록 개선되었다. 플랫폼에 등록된
모든 MBean의 정보를 표시한다. 모든 플랫폼 MBean은 이 탭을 통해 접근할 수 있다. 왼쪽에 현재
실행중인 모든 MBean을 트리 구조로 표시한다. MBean을 선택하면 MBeanInfo와 설명자가
오른쪽에 표시된다(그림 3).


그림 3. JConsole의 MBean 탭
JConsole의 MBean 탭

Attributes 노드를 선택하면 MBean의 모든 속성을 표시한다(그림 4).


그림 4. MBean Attributes
MBean 속성

오른쪽에 표시된 속성과 값은 앞에서 설명한 java.lang.management 패키지의 ThreadMXBean
API를 통해 접근할 수 있다는 점을 주목하자. 나열된 속성 값을 더블클릭하면 추가 정보를 얻을 수
있다. 굵게 표시된 속성값은 확장할 수 있다. 예를 들어, AllThreadIds 값을 더블클릭하면 22개
스레드의 스레드 ID를 모두 표시한다(그림 5).


그림 5. 확장된 속성 값
확장된 속성 값

쓰기 가능한 속성은 파란색으로 표시되는데, 클릭한 다음 새 값을 입력해 편집할 수 있다. 예를 들어,
그림 5의 JConsole 화면에서 ThreadContentionMonitoringAvailable 속성을 이 방식으로
편집할 수 있다.

왼쪽 트리 구조에서 Operations 노드를 선택하면 MBean과 연관된 동작들을 표시한다. MBean
동작은 오른쪽에 버튼으로 표시되는데, 클릭하면 지정한 메서드를 호출한다. 그림 6은
ThreadMXBean의 가용한 동작들을 보여준다.


그림 6. MBean Operations
MBean 동작

핫스팟 진단 MBean

자바 SE 6부터 JConsole은 핫스팟 진단(HotSpot Diagnostic) MBean을 지원한다. 이 MBean은
즉석(on-the-spot) 동작을 수행하기 위해 이번 버전에 도입되었다. 이 API를 통해 사용자는 실행
중에 힙을 덤프하거나 다른 VM 옵션을 설정할 수 있다. MBean 탭에서 com.sun.management
노드를 확장하고 HotSpotDiagnostic을 선택하면 핫스팟 진단 MBean에 접근할 수 있다.
그림 7에서 핫스팟 진단 MBean에서 가용한 메서드들을 볼 수 있다.


Figure 7. 핫스팟 진단 MBean
핫스팟 진단 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 플러그인
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 클라이언트 개발 팀의 스태프 소프트웨어 엔지니어다.

+ Recent posts