넷빈(netbeans)6.8에서 HeapWalker 사용하기

0

Written on 오전 7:24 by 강여사(J.Y.Kang)

본 예제의 샘플 프로젝트는 다음 경로에서 다운받을 수 있습니다.

http://docs.google.com/leaf?id=0B55-rdrBfsK5ODA2MzBmZTgtYzJiYS00NWQ4LWFiODAtMjUxMWI2MTg5NDNk&hl=ko

이번 예제에서는 프로파일링 시 OOM(Out Of Memory) 발생시 힙 덤프를 자동 생성하며, 해당 덤프에 대한 분석을 가능하게 해주는 HeapWalker 기능에 대해 알아 보겠습니다.

이번 예제에서 사용할 프로젝트는 PrimeNumbers (SE) 입니다.

우선 해당 프로젝트를 실행하여 어떤 내용의 프로젝트인지 살펴보겠습니다.

프로젝트를 실행시키면 아래와 같은 프로그램이 제시되는데 입력한 값에 대한 소수를 구해줍니다. 그럼 다음과 같이 1000000 을 입력하고 아래 버튼을 누릅니다. 계산된 소수는 999983 입니다.
다시 한번 Calculate Prime Numbers 버튼을 클릭하면 출력창에 OOM 이 떨어집니다. java heap size
그럼 이제 이 문제에 대해 프로파일을 해보도록 하겠습니다.

프로젝트 - 프로파일

메모리 프로파일을 선택하고 객체 생성과 가비지 컬렉션 모두 기록과 할당을 위한 스택 추적 기록을 체크 한 후 실행합니다.
프로파일 컨트롤 패널에서(왼쪽) 라이브 결과를 누르고 프로그램을 아까와 같이 1000000 을 입력한 후 계산 버튼을 클릭합니다.
아까와 마찬가지로 다시 한번 버튼을 클릭하면 아까처럼 OOM 이 떨어집니다.
해당 프로그램을 종료하면 스냅샷 찍기 여부에 관한 팝업창이 뜹니다.

예 선택

프로파일링 도중 OOM 이 떨어져서 자동으로 힙 덤프가 생성되어 해당 덤프 분석을 위한 HeapWalker 동작 여부에 대한 확인창이 제시됩니다.

예 선택

아래 그림이 힙덤프에 대한 힙워커(heapwalker) 분석 내용입니다.

아래쪽에 보면 스레드 보기 링크가 있습니다. 클릭 클릭하면 관련 클래스에 대한 링크들이 제시됩니다.
HeapWalker의 클래스 탭을 누른 후 크기로 정렬 합니다.
가장 큰 크기를 차지 하고 있는 int[] 에서 마우스 오른쪽을 클릭하여 인스턴스 뷰에서 보기를 선택합니다.
아래 그림이 인스턴스 뷰인데 오른쪽 필드 부분을 확장하면 묶음 단위의 숫자가 진행되면서 소수가 아닌 수는 -1 로 소수는 소수대로 값이 나타납니다.
아래 참조쪽에서 this 에서 오른쪽 마우스를 클릭하여 가장 근접한 GC루트 보기를 선택합니다.
해당 내용에 가장 근접한 GC 루트는 complete_ ... 라고 되어 있습니다.
그럼 그림과 같이 해당 위치에서 다시 마우스 오른쪽을 클릭하여 소스로 이동을 선택합니다.
소스쪽에 오면 해당 complete_가 Map 으로 되어 있는데 이에 대한 사용을 찾으려면 다음과 같습니다.
complete_ 에서 마우스 오른쪽을 클릭하고 find usage (사용법 찾기)를 선택합니다.
아래 그림과 같이 팝업창이 나타나는데 현재 프로젝트인 PrimeNumbers를 찾아 선택합니다.

찾기

그럼 아래창으로 caller와 callee 가 각각 왼쪽 아이콘에 따라 나타납니다.

아래 그림은 callee가 표현된 그림입니다.

....put(XX) 제시된 해당 메소드를 더블 클릭하면 소스로 이동됩니다. 바로 이 부분이 OOM 발생의 문제 부분입니다.
넷빈에서는 프로파일시 OOM 이 발생하면 자동으로 힙덤프를 생성하고 HeapWalker가 동작합니다.

만약 기존에 작성된 힙 덤프가 있다면 profile - load heap dump 메뉴를 사용하면 됩니다.

이번 예제에서는 넷빈 6.X 의 새 기능인 HeapWalker에 대해서 알아 봤습니다.

그동안 힙 덤프 분석을 위해서 여러 툴 들이 제시됐지만 많이 불편했는데 이 HeapWalker는 나름 또 쓸만하네요.

계속...



넷빈(netbeans)6.8에서 프로파일링 - 스레드 진단

0

Written on 오전 6:41 by 강여사(J.Y.Kang)

본 예제에서 제시된 샘플 프로젝트는 다음 경로에 있습니다.

http://docs.google.com/leaf?id=0B55-rdrBfsK5YWUyNGQ3ZGUtYmE4Zi00ZWU3LTk2NDEtMTZjMzFmODM4NWUw&hl=ko

이번에 할 작업은 UI 프로그램에서 스레드 상태를 진단하고 문제가 되는 지점을 찾아 내는 방법에 대해 알아보겠습니다.

프로젝트 열기 (MonitoredThreads)

실행 해당 프로그램은 버튼이 2개 있는 간단한 UI 프로그램입니다.
그러나, 이때 Start! 버튼을 누르게 되면 일정 시간이 지날때까지 아무 것도 동작하지 않습니다.
아래 그림 처럼 경과시간이(30초) 지나야만 기타 다른 버튼 (Exit 혹은 X) 등이 동작합니다.
왜 이런일이 생긴 걸까요?

이제 프로젝트를 프로파일링 해보겠습니다.

프로젝트 - 프로파일

우선 모니터를 선택하여 스레드 모니터링 활성화에 체크(확인)를 하고 실행합니다
프로그램이 시작되면서 뒤편으로 스레드가 상태별로 보여집니다. (각 색상은 해당 상태에 대한 내용입니다. 녹색-실행중, 보라-휴면, 노랑-대기, 빨강-모니터)
그러다 Start버튼을 누르면 이 중 변화하는 스레드가 있습니다.

AWT-EVENTQUEUE-0 입니다. 대기에서 실행으로 바뀌는 군요.

다시 30초가 경과되면 팝업창이 나타나고 그때 스레드 상태 역시 다시 대기상태로 빠집니다.
해당 프로그램을 종료하면 아래 그림과 같은 정보 알림창이 뜹니다. OK
AWT_EVENTQUEUE-0 를 더블클릭하면 해당 스레드에 대한 좀더 자세한 내용이 도식화됩니다.

AWT-EVENTQUERE-0 는 원래 이벤트 큐를 대기하는 일을 담당하는 스레드 입니다.

그럼에도 불구하고 Start! 버튼 클릭시 상태가 실행중으로 바뀌는 바람에 프로그램이 먹통이 된거지요. 이번에는 모니터링이 아니라 분석을 위해 다시 프로파일링을 시작합니다.
CPU 성능 분석을 실행합니다.
스레드 화면이 뒤에 나타나면 아까와 마찬가지로 프로그램에서 Start! 버튼을 눌러 상태 변화를 확인합니다.

프로그램을 종료하면 수행된 결과의 스냅샷을 찍는 정보창이 나타납니다.

예 선택

스냅샷에 AWT-EVENTQUERE-0 에 jButton1ActionPerformed 메소드에서 마우스 오른쪽을 클릭하여 소스로 이동을 선택합니다.
jButton1ActionPerformed 아래 while 문을 살펴보면 잘못 작성되어 있음을 발견할 수 있습니다.
위의 그림에 해당 내용을 주석처리합니다.
프로파일링을 다시 시작합니다.
CPU 성능분석 - 실행
이번에는 Start! 버튼을 눌러도 AWT-EVENTQUEUE-0 상태에는 변화가 없습니다.
물론 다른 버튼을 누르면 바로 반영됩니다. (Exit 나 X)

다시 소스를 열어 아래 주석으로 되어 있는 SwingWorker 부분을 주석 해제를 합니다. (그림 참조)
작성된 SwingWorker.java 의 내용은 같은 패키지 안에 있습니다.
다시 프로파일을 시작합니다.
CPU 성능분석 - 실행
프로그램을 시작했을 때 스레드는 다음과 같습니다.
그러다 Start! 버튼을 누르면 AWT-EVENTQUEUE-0 는 여전히 대기상태로 진행되면서, SwingWorker 스레드가 새로 실행됩니다.
프로그램을 종료하면 스냅샷 찍기에 대한 확인창이 뜹니다.

예 선택
Call Tree 확인
이상 스레드 모니터링에 대한 간단한 예제 였습니다.

계속...