JUnit로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

JUnit로 검색한 결과
등록일:2008-04-23 14:06:48
작성자:
제목:애플리케이션 테스트, 프로파일, 모니터링


난이도 : 중급

Martin Streicher , Editor-in-Chief, Linux Magazine

2007 년 8 월 14 일

자 바™ 애플리케이션 프로파일링을 위해 Eclipse Test & Performance Tools Platform(이하, TPTP)를 어떻게 사용하는지와 메모리 사용량을 측정하고, 메모리 누수(memory leaks)를 확인하며, 성능 병목(performance bottlenecks)을 없애는 법을 배우겠습니다.

시작하기 전에

이번 튜토리얼에 대해

이 튜토리얼은 이클립스와 TPTP를 어떻게 설치하고, 실행한 자바 애플리케이션의 프로파일링을 어떻게 하는지 보여주기 위해, 한 단계씩 차근차근 진행할 것이다.




필요한 지식과 소프트웨어

자바 소프트웨어 개발이나 테스트와 프로파일링을 포함한 개발 주기 전체에 걸친 경험이 있으면 유리하다. 또한 직접 커맨드로 소프트웨어를 설치한 경험이나, 자바 CLASSPATH처럼 셸(shell)이나 전역 시스템 환경 변수를 설정, 관리해본 경험이 있으면 더 좋다. 이클립스와 SWT(Standard Widget Toolki)에 대한 경험 또한 도움이 된다.

시 작하기 전에, 여러분이 사용하는 UNIX®, Linux®, Mac OS X나 Microsoft® Windows® 시스템에 몇 가지 소프트웨어를 설치해야만 한다. 자바 가상 머신(JVM), 이클립스 플랫폼의 복사본, Eclipse TPTP 런타임과 TPTP에 의존하는 소프트웨어 몇 가지가 필요하다. 또한 애플리케이션을 시작하고, 프로파일링을 해주는 TPTP의 에이전트 컨트롤러(Agent Controller)가 필요하다. 정리해 보면 다음과 같다.






시스템 요구사항

사 용하는 시스템에 JVM과 이클립스가 설치되어 있지 않다면, 모든 소프트웨어를 위해 사용할 수 있는 여유 공간이 적어도 300MB 이상 있는지 확인하자. 또한 JVM 구동을 위한 충분한 물리적 메모리가 필요하다. 일반적으로 64MB나 그 이상의 물리적 메모리를 추천한다.





TPTP 소개

자바 코드로 애플리케이션이나 서블릿을 작성하는 것은, 견고하며 개발 완료 수준의 품질이 보장되는 프로그램을 전달하기 위한 긴 과정 중 첫 번째 단계일 뿐이다. 코드는 반드시 해당 오퍼레이션과 정확성을 점검하기 위해 테스트해야 한다. 코드는 성능 저하를 불러오는 병목 현상과 특히 메모리와 같은 자원 낭비와 부주의한 사용을 제거하기 위해 프로파일링되어야 한다. 또한 애플리케이션 오류와 미수로 그쳤거나 실제 행해진 공격을 세밀하게 찾아내기 위해서뿐만 아니라 개선과 최적화를 위한 가능성과 사용 패턴을 확인하기 위해 모니터링되어야 한다.

이클립스 TPTP는 무엇인가

테 스트, 프로파일, 코드 모니터링을 위한 도구는 많이 존재하지만, 대규모로 통합된 도구는 거의 없다. 게다가 이러한 도구는 일반적으로 벤더 별로 각각 제공되어, 매번 다른 사용자 인터페이스(UI), 컴파일러, 진단 도구를 파악하고 배우는 데 값진 시간과 노력을 허비하게 된다. 시간과 돈을 측정해 볼 때, 이렇게 특정 회사 소유의(proprietary) 도구는 터무니 없을 정도의 투자를 필요로 한다.

그러나 만약 테스트, 프로파일러, 모니터링 도구가 오픈소스라면 어떻게 생각하는가? 그리고 이 도구가 확장성이 뛰어나, 어느 벤더나 개발자라도 새로운 도구를 만들거나 기존 도구를 향상시킬 수 있다면? 그리고 이 도구가 대중적이고 친숙한 기존 도구와 매우 훌륭하게 통합된다면? 꿈 같은 얘기일까? 전혀 꿈이 아니다.

이클립스 TPTP는 소프트웨어 아키텍처이며 테스트, 성능, 모니터링 도구를 포함하도록 이클립스 플랫폼을 확장한 몇 가지 컴포넌트로 되어 있다. 일부 자바, C, C++ 개발자들은 다른 개발자들을 위해 독특한 도구를 만드는 데 TPTP를 이용하기도 하고 또 다른 개발자들은 사용자들을 위해 애플리케이션을 빌드하고 배치하는 데 TPTP 기반 도구와 기타 이클립스 기능을 한데 엮기도 한다.




위로


TPTP의 목적

간 단하게 말해 TPTP는 "소프트웨어 개발자들이 전문화되고, 차별성을 갖고, 공동으로 사용할 수 있는 일반적이고, 확장 가능하며, 표준 기반 도구 플랫폼 구축"을 목적으로 하는 이클립스 재단의 최고 수준(top-level) 프로젝트다. 핵심만 다시 정리해 보면, TPTP는 자동화된 소프트웨어 품질 관리를 위해 또 다른 도구를 빌드해 주는 도구다.

실제로 현재 발표된 TPTP는 핵심 부분과 핵심 부분에 기반을 둔 세 가지 도구를 포함한다.

TPTP
TPTP 는 UI 개발, 데이터 컬렉션, 역할 기반(rule-based)의 데이터 쿼리와 애플리케이션 컨트롤을 위한 핵심 기반을 제공한다. 예를 들어, TPTP는 다른 도구가 재사용하고, 확장할 수 있는 많은 마법사 기능을 제공한다. 또한 프로그래밍 인터페이스와 로컬 혹은 원격에서 데이터 컬렉션 실행을 편리하게 해주는 데몬을 제공한다.
TPTP 테스팅 도구
이 프로젝트는 모든 종류의 애플리케이션 테스트를 자동화하기 위한 부가 서비스를 제공한다. 현재 발표된 버전에서는 자동화된 테스트 기능을 갖춘 JUnit을 지원한다. 이 기능은 직접 테스트를 작성하고, 결과를 보관하며, 테스트 지점을 지정할 수 있는 시스템과 웹 애플리케이션 테스트를 위한 자동화된 시스템을 제공한다. 이 웹 애플리케에션 테스트 시스템에는 웹 브라우저 세션과 인증 결과를 녹화하고, 다시 재생할 수 있는 기능을 갖고 있는 녹화기(recorder)가 포함된다. 또한 이클립스 V4.1에는 SWT 기반 인터페이스에서 마우스와 키보드 이벤트를 녹화하고, 재생할 수 있는 GUI 녹화기(recorder)의 초기 배포 버전이 이미 포함되어 있다.
TPTP 모니터링 도구
이 프로젝트는 애플리케이션에서 수집된 통계 정보와 로그 파일에서 데이터를 수집 분석해 시각화한다.
TPTP 트레이싱/프로파일링 도구
이 프로젝트는 운용중인 애플리케이션에서 CPU와 메모리를 포함한 자원 사용을 수집하고 분석하기 위해 TPTP를 확장한다. 또한 트레이싱 도구를 이용해 실행중인 프로세스와 상호 작용할 수 있다. 예를 들어, 가비지 컬렉션을 직접 강제로 실행할 수 있고, 메모리 "누수"를 찾아내 수정하기 위해 현재 있는 객체 풀을 점검할 수 있다.

그 외에도 TPTP에는 에이전트 컨트롤러라 는 데몬이 들어있다. 에이전트 컨트롤러는 이클립스 워크벤치(Eclipse Workbench)와 테스트 대상이 되는 애플리케이션 사이의 연락을 책임진다. 이클립스 대신에 자바 애플리케이션을 로컬이나 원격에서 실행할 수 있으며, 애플리케이션 로그 파일을 포함해서 애플리케이션 메트릭스를 워크벤치에 전달한다.

이제 이번 튜토리얼에서 남은 것은 자바 기술을 위한 TPTP 프로파일링 도구의 몇몇 부분을 시연하는 것이다.


--다음페이지--



필수적으로 필요한 소프트웨어와 컴포넌트 설치하기

이 튜토리얼을 시작하기 전에 필요한 소프트웨어와 컴포넌트를 설치하고 구성해야만 한다.

J2SE와 J2RE 설치

J2SE V1.4와 V1.4 J2RE를 다운로드해 설치하자(이미 시스템에 J2SE V.1.4.2_10이나 그 이상의 버전이 있다면 이 단계는 지나가도 된다).


일반적으로 J2SE SDK와 JRE는 스스로 압축이 풀리는 바이너리로서 배포된다. 리눅스에서 설치도 다음과 같이 매우 쉽다.



Listing 1. J2SE SDK와 JRE 설치
                    
% cd ~
% mkdir ~/java
% cd ~/java
% mv ~/j2sdk-1_4_2_10-linux-i586.bin .
% mv ~/j2re-1_4_2_10-linux-i586.bin .
% chmod +x j2sdk-1_4_2_10-linux-i586.bin \
j2re-1_4_2_10-linux-i586.bin
% ./j2sdk-1_4_2_10-linux-i586.bin
.
% ./j2re-1_4_2_10-linux-i586.bin
.
% ls -F
j2re1.4.2_10/ j2sdk1.4.2_10/




위로


이클립스 업데이트 관리자를 사용해 TPTP 설치하기(선택사항)

이미 이클립스가 설치되어 있다면, TPTP를 설치하기 위해 이클립스 업데이트 관리자(Eclipse Update Manager)를 사용해도 된다.

  1. Help > Software Updates > Find and Install 클릭
  2. Search for new features to install 옵션을 선택하고, Next 클릭
  3. New Remote Site를 클릭하고, TPTP Update Sitehttp://eclipse.org/tptp/updates/site.xml를 각각 이름과 URL로 정하고, Finish 클릭
  4. 설치하려는 기능을 모두 선택하고, Next 클릭
  5. 라이선스 동의를 체크하고, Next를 클릭한 다음, Finish를 클릭
  6. 확인 창에서 Install All을 클릭하면 설치가 완료되고 이클립스가 재시작된다.

이제 에이전트 컨트롤러 설치에 대해 상세하게 설명하고 있는 에이전트 컨트롤러 설치 부분을 넘어갈 수 있다. 아직 이클립스를 설치하지 못 했다면, 계속 읽어 나가자.




위로


이클립스 V3.1 SDK 설치

사용하는 플랫폼에 맞는 이클립스 3.1 SDK를 다운로드하자. Eclipse Downloads에 서 SDK를 찾을 수 있다. 일반적으로 설치는 Eclipse.tar.gz 파일을 원하는 디렉터리에 압축만 해제하면 끝날 만큼 매우 쉽다. 예를 들어, 리눅스를 사용한다면 이클립스 V3.1 SDK tar 버전을 받아서, 다음 명령어를 사용해 ~/java/ 디렉터리에 압축을 해제하면 된다.

% cd ~/java
% mv ~/eclipse-SDK-3.1.1-linux-gtk.tar.gz .
% tar zxvf eclipse-SDK-3.1.1-linux-gtk.tar.gz

이클립스가 제대로 설치되었는지 확인해 보려면 이클립스를 압축 해제한 디렉터리로 가서, PATH에서 java 명령어를 실행할 수 있는지지 확인하고, java -jar eclipse/startup.jar를 실행하자. 예를 들면 다음과 같다.


Listing 2. 이클립스가 성공적으로 설치되었는지 확인하기
                    
% export JAVA_DIR=$HOME/java
% export JAVA_HOME=$JAVA_DIR/j2sdk1.4.2_08/sdk
% export PATH=$JAVA_HOME/bin
% export CLASSPATH=$JAVA_HOME
% cd $JAVA_DIR
% java -jar eclipse/startup.jar

워크스페이스 생성을 위해 디렉터리는 $HOME/java/workspace를 선택하자. 이 디렉터리에 이클립스에서 만들어지는 모든 프로젝트가 포함될 것이다(물론 프로젝트가 많다면, 워크스페이스당 하나의 프로젝트를 포함할 수 있도록 나중에 워크스페이스를 다른 디렉터리로 변경할 수 있다).




위로


EMF SDK 2.1 설치

실 행중인 이클립스가 있다면 종료하고, EMF SDK V3.2를 다운로드하자(EMF 웹 사이트에 의하면, EMF는 "모델링 프레임워크이며, 구조화된 데이터 모델을 기반으로 하는 애플리케이션과 빌딩 도구를 위한 코드 생성 기능을 제공한다"). 파일을 다운로드한 후에, 이클립스를 받은 폴더로 이동한 다음 emf-sdo-SDK-2.1.0.zip을 압축을 해제하자. 예를 들면 다음과 같다.


Listing 3. emf-sdo-SDK-2.1.0.zip 압축 풀기
                    
% cd $JAVA_DIR
% ls
eclipse j2sdk1.4.2_08
% mv ~/emf-sdo-SDK-2.1.0.zip .
% unzip emf-sdo-SDK-2.1.0.zip
creating: eclipse/features/
creating: eclipse/features/org.eclipse.emf.ecore.sdo_2.1.0/
creating: eclipse/features/org.eclipse.emf_2.1.0/
inflating: ...




위로


XSD 2.1 설치

XSD SDK 2.1을 다운로드하자(이 프로젝트의 웹 사이트에 따르면, XSD는 "W3C XML 스키마 규약에 따른 XML 스키마 컴포넌트를 처리하기 위한 API를 제공하는 라이브러리다"). 받은 파일을 이클립스를 포함하고 있는 디렉터리로 옮기고, unzip xsd-SDK-2.1.0.zip를 실행하자. 예를 들면 다음과 같다.

% cd $JAVA_DIR
% mv ~/xsd-SDK-2.1.0.zip .
% unzip xsd-SDK-2.1.0.zip

어떤 파일을 덮어쓰기 해야 한다고 하면, 간단히 y(소문자)를 누르자.




위로


UML V2.0 메타모델(Metamodel) 구현체 설치하기

TPTP 에서 UML(Unified Modeling Language)을 사용하려면 UML V2.0 메타모델 구현체를 설치해야 한다. 이클립스 V.3.1.1을 사용한다면, UML2 V1.1.1을 다운로드하고 나서, 이클립스가 포함되어 있는 디렉터리에 압축을 해제하자.

% cd $JAVA_DIR
% mv ~/uml2-1.1.1.zip .
% unzip uml2-1.1.1.zip




위로


TPTP 런타임 설치

다 음 단계로 두 가지 시스템을 통합하는 데 필요한 TPTP 기능과 이클립스 플러그인이 들어있는TPTP 런타임을 다운로드하자. TPTP를 설치하려면 이클립스가 포함되어 있는 디렉터리로 변경하고, unzip tptp.runtime-TPTP-4.1.0.zip을 실행하자. 예를 들면 다음과 같다.

% cd $JAVA_DIR
% mv ~/tptp.runtime-TPTP-4.1.0.zip .
% unzip tptp.runtime-TPTP-4.1.0.zip




위로


에이전트 컨트롤러 설치

에 이전트 컨트롤러는 애플리케이션을 이클립스에서 실행하고, 프로파일링 데이터를 추출하기 위해 해당 애플리케이션과 상호 작용하는 TPTP의 핵심 컴포넌트다. OS에 적합한 에이전트 컨트롤러 런타임을 다운로드하자. 그 다음으로 이클립스가 들어있는 같은 디렉터리에서 tptpd라는 이름으로 디렉터리를 만들고, 그 디렉터리에 에이전트 컨트롤러 압축을 푼다. 명령은 다음과 같다.

% mkdir $JAVA_DIR/tptpd
% cd $JAVA_DIR/tptpd
% mv ~/tptpdc.linux_ia32-TPTP-4.1.0.zip .
% unzip tptpdc.linux_ia32-TPTP-4.1.0.zip

실행 후에 다음 두 개의 에러를 볼 수도 있다.

linking: lib/libxerces-c.so      
warning: symbolic link (lib/libxerces-c.so) failed

linking: lib/libxerces-c.so.24
warning: symbolic link (lib/libxerces-c.so.24) failed

이 경우 다음 명령을 직접 입력해 링크 두 개를재생성해야만 한다.

% cd $JAVA_DIR/tptpd/lib
% rm libxerces-c.so libxerces-c.so.24
% ln -s libxerces-c.so.24.0 libxerces-c.so
% ln -s libxerces-c.so.24.0 libxerces-c.so.24

에이전트 컨트롤러 디렉터리 추가하기

에이전트 컨트롤러를 사용하려면 LD_LIBRARY_PATH 밑에 lib 디렉터리를 추가해야 한다. 예를 들어, 리눅스를 사용하고 위에서 제시한 디렉터리 구조를 동일하게 적용했다면, 다음과 같이 $JAVA_DIR/tptpd/lib를 추가하면 된다.

% export LD_LIBRARY_PATH=$JAVA_DIR/tptpd/lib:$LD_LIBRARY_PATH

또한 Controller의 lib과 bin 디렉터리에 대한 실행 권한을 보장해야만 한다. 그렇게 하기 위해서는 다음 커맨드를 실행하자.

% chmod +x $JAVA_DIR/tptpd/{bin,lib}/*

이제 PATH 상에 에이전트 컨트롤러를 구성하고, 시작하고, 중지하는 스크립트를 추가하자.

% export PATH=$JAVA_DIR/tptpd/bin:$PATH

사용하는 환경에 맞게 에이전트 컨트롤러 구성하기

마지막으로 여러분이 사용하는 환경에 맞춰 에이전트 컨트롤러를 구성해 보자. 에이전트 컨트롤러의 bin 디렉터리로 이동하고 SetConfig.sh를 실행하자.

% cd $JAVA_DIR/tptpd/bin
% ./SetConfig.sh

구성 스크립트가 질문을 하면 기본값을 받아들이라. 구성 스크립트를 실행하면 에이전트 컨트롤러의 파일 구조에 있는config/serviceconfig.xml 파일이 만들어진다.

에이전트 컨트롤러 테스트

에이전트 컨트롤러를 테스트하기 위해, RAStart.sh를 실행하자. 에이전트 컨트롤러를 멈추려면 RAStop.sh를 실행한다.


Listing 4. 에이전트 컨트롤러 중지하기
                    
db% RAStart.sh
Starting Agent Controller
RAServer started successfully
% RAStop.sh
RAServer stopped, pid = 5891
RAServer stopped, pid = 5892
RAServer stopped, pid = 5893
RAServer stopped, pid = 5894
RAServer stopped, pid = 5895
RAServer stopped, pid = 5896
RAServer stopped, pid = 5897
RAServer stopped, pid = 5898
RAServer stopped, pid = 5899
RAServer stopped, pid = 5900
RAServer stopped, pid = 5901
RAServer stopped, pid = 5902
RAServer stopped, pid = 5904
RAServer stopped, pid = 5905
RAServer stopped, pid = 5906

이제 끝났다! 이클립스를 다시 시작하자. 이제 그림 1과 같은 새로운 버튼을 이클립스 도구 모음에서 볼 수 있다 바로 TPTP 프로파일 버튼이다. TPTP는 설치되었고, 다음 부분을 계속할 준비가 됐다.


그림 1. TPTP 프로파일 버튼
TPTP 도구 버튼

--다음페이지--

자바 애플리케이션 프로파일링

이제 TPTP 설치가 완료됐고, 돌아가고 있다. 이클립스를 실행하자.

예제 애플리케이션

프로파일링을 위한 자바 애플리케이션은 Listing 5에서 볼 수 있다.


Listing 5. 작은 수의 객체들 묶음의 이동에 대한 간단한 자바 애플리케이션
                    
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class SpaceShipToy {
/*
* To build a spaceship, you need a capsule, a booster,
* three stages, and two monkeys (borrowed
* from a Barrel of Monkeys).
*/
public Capsule capsule = new Capsule();
public Booster booster = new Booster();
public Stage[] stage = new Stage[3];

public SpaceShipToy()
{
for (int i = 0; i < 3; i++)
stage[i] = new Stage();
}

private void _killTime(int seconds)
{
if (seconds <= 0)
return;

for (int i = 0; i < seconds; i++);
}

static final int MINUTE = 60;
static final int CAPSULE = 2 * MINUTE;
static final int BOOSTER = 5 * MINUTE;
static final int STAGE = 3 * MINUTE;
static final int MONKEY = 10 * MINUTE;

class Capsule {
public Monkey chimp1 = new Monkey(), \
chimp2 = new Monkey();

public Capsule() {
System.out.println("Start building the capsule...");
_killTime(CAPSULE);
chimp1.build();
chimp2.build();
System.out.println("Capsule complete.");
}
}

class Booster {
public Booster() {
System.out.println("Start booster...");
_killTime(BOOSTER);
System.out.println("Blast off.");
}
}

class Stage {
public Stage() {
System.out.println("Start stage...");
_killTime(STAGE);
System.out.println("Stage complete.");
}
}

class Monkey {
public void start() {
System.out.println("Start the monkey business...");
}

public void build() {
start();
_killTime(MONKEY);
finish();
}

public void finish() {
System.out.println("Monkey business complete.");
}
}


public static void main(String[] args) throws \
java.io.IOException
{
final int NUMBERTOYS = 9;

BufferedReader in = new
BufferedReader(new InputStreamReader(System.in));
SpaceShipToy[] toys = new SpaceShipToy[NUMBERTOYS];
String input = in.readLine().trim();

System.out.println("Toy factory is up and running...");
System.out.flush();

for (int i = 0; i < NUMBERTOYS; i++)
toys[i] = null;

while (!input.equalsIgnoreCase("q")) {
if (input == null || input.length() != 1
|| !Character.isDigit(input.charAt(0))) {
System.err.println ("Unknown option. Try 0-9, q");
input = in.readLine().trim();
continue;
}

int number = Integer.valueOf(input).intValue();
if (number == 9) {
new SpaceShipToy();
System.out.println("Whoops... Lost one...");
}
else {
if (toys[number] != null) {
System.out.println("Shipping toy # " + number);
toys[number] = null;
}
else {
System.out.println("Building toy # " + number);
toys[number] = new SpaceShipToy();
}
}

input = in.readLine().trim();
}
}
}

이 자바 애플리케이션은 단순하다. 장난감 로켓 배를 "만들고", "선적"한다. 각각의 장난감은 다른 객체를 포함하는 자바 객체로 표현되는데 각각 장난감의 일부분을 나타낸다. 각 장난감은 장난감의 각 부분을 만드는데 일정한 시간이 걸린다.

애플리케이션을 사용하기 위해서는 0에서 8 사이의 숫자를 입력해 장난감을 만들어야 한다. 같은 키를 반복해 입력했다면, 만들어진 장난감은 "선적"되며, 해당 객체는 가비지 컬렉션에 의해 레퍼런스가 제거된다. 그 결과 한 번에 메모리에 최대 9개의 장난감을 불러 들일 수 있다(9개의 장난감은 만들어졌지만, 선적되지는 않았다고 가정함).

메모리 누수 확인을 위한 참조되지 않는 객체를 만들기 위해 9 키를 누르자. 애플리케이션을 종료하려면 q 키를 누르면 된다.




위로


프로파일링 세션 실행

"Toy Factory"를 실행, 프로파일링하기 위해 이클립스와 TPTP를 사용하자. TPTP는 활성화된 객체의 숫자, 실행 시간 등 부가적인 정보를 보여줄 수 있다. 이클립스와 TPTP를 사용하는 과정은 다음과 같다.

  1. 에이전트 컨트롤러 실행
  2. 에이전트 컨트롤러의 bin 디렉터리로 변경하고, RAStart.sh 실행
    % cd $JAVA_DIR/tptpd/bin
    % ./RAStart.sh


  3. 이클립스에서 워크벤치로 이동한 다음, File > New > Project를 클릭해 새로운 자바 프로젝트를 생성하자. Options 목록에서 Java Project를 선택하고 Next를 클릭한다.
  4. 다음 창에서 프로젝트 이름을 Toy Maker로 주고, Finish를 클릭하자. 새로운 프로젝트의 이름인 "Toy Maker"는 Package Explore 패널에서 확인할 수 있다.
  5. example 패키지 안에 SpaceShipToy라는 새로운 자바 클래스를 만들자. File > New > Class를 클릭하자.
  6. 다음으로 나오는 창에서 Package 필드에는 example을 넣고, Name 필드에는 SpaceShipToy를 입력하자. 이 창에서 다른 값은 설정하지 않는다.
  7. Finish를 클릭하자. 이제 새로 생성한 클래스의 구조(skeleton)를 확인할 수 있다.
  8. 이클립스 클래스 편집기에 Listing 1에 나왔던 코드를 붙여 넣는다. 비어 있는 클래스 정의 부분은 변경됐지만, package example 선언이 남아 있는지 확인하자. 코드를 저장해 변경 사항을 적용하면 이클립스가 새 버전의 클래스를 자동으로 다시 컴파일한다.
  9. 애플리케이션을 실행하고 싶은 경우, Run > Run...을 클릭하고, Java Application을 더블 클릭한 다음, SpaceShipToy를 선택한 후, Run을 클릭하자. 애플리케이션의 작동을 확인하기 위해 Windows > Show View...를 클릭하고, Console을 선택하자.
  10. 1(숫자 1)을 입력하고 Return을 누르자. 화면이 그림 2처럼 보일 것이다.


    그림 2. 이클립스에서 실행되는 장난감 공장
    이클립스에서 애플리케이션 실행




위로


동일 애플리케이션 프로파일링

위에서 다룬 똑 같은 애플리케이션을 프로파일링하는 과정은 다음과 같다.

  1. TPTP Profile을 클릭한 다음, Profile...을 선택하자.
  2. SpaceShipToy을 다시 보기 위해 Java Application을 확장하자. Profile 창은 Run을 클릭했을 때 나타나는 Run 창과 비슷하지만, Profile이라는 추가 탭이 있다.
  3. 프로파일러 내에서 애플리케이션을 시작하기 위해 Profile을 클릭하자. Perspective가 자동으로 변경되지 않으면, Window > Open Perspective > Other...를 클릭한 다음 Profiling and Logging을 선택하자.
  4. Profiling과 Logging perspective가 나타났을 때, Profiling Monitor 뷰의 내용을 확장하고, <monitoring>으로 시작하는 줄을 선택하자. 이 줄을 선택했을 때, Console 뷰가 나타난다.
  5. 0, 1, 29를 입력하자. 화면에 그림 3과 같은 내용이 나온다.


    그림 3. 실행중인 애플리케이션의 Profiling과 Logging perspective
    Profiling and Logging perspective

  6. Memory Statistics 뷰를 클릭하고, example 패키지와 관련된 줄을 확장하자. 이 뷰는 그림 4와 같다. 각 객체는 4개의 인스턴스(장난감을 "만들기" 위한 세 개와 참조되지 않은 장난감 하나의 인스턴스)를 갖고 있다.


    그림 4. 세 개의 toy 오브젝트와 하나의 참조되지 않은 toy 오브젝트가 빌드된 후 메모리 소모 내역
    메모리 통계 보기

Memory Statistics 뷰에 있는 칼럼은 인스턴스와 사용하고 있는 메모리 통계를 추적해 준다.

  • Total Instances는 클래스의 총 인스턴스 개수를 반영한다.
  • Live Instances는 얼마나 많은 인스턴스가 계속 참조되고 있고, 가비지 컬렉터에 의해 수집되지 않았는지 보여준다.
  • Collected는 얼마나 많은 클래스의 인스턴스를 가비지 컬렉터가 수집했는지 보여준다.
  • Total Size (bytes)Active Size (bytes)는 모든 인스턴스가 사용하고 있는 누적된 총 메모리 양과 현재 존재하는 인스턴스에 의해 실제로 사용되는 메모리 양을 각각 보여준다.



위로


시험 실행 끝내기

이번 시험 실행을 끝마치려면 Console 뷰를 뒤로 넘기고 0, 12 숫자 키를 다시 누른다. 가비지 컬렉션 을 강제로 하기 위해 Monitoring 뷰에 있는 trash 아이콘을 클릭하자. 가비지 컬렉션이 완벽하게 수행됐다면 참조되지 않은 모든 객체를 수집해 간다. 언제든지 Refresh(그림 5)를 클릭함으로써, 현재 Perspective에 있는 모든 뷰를 새로 고칠 수 있다.


그림 5. Refresh 버튼
Refresh 버튼

--다음페이지--

원하는 데이터 찾기

Profiling과 Logging perspective는 애플리케이션 상태에 대한 많은 양의 정보를 보여주는 뷰 집합을 제공한다. 이 목록을 보기 위해서는 Window > Show View > Other...를 클릭한 다음, Profiling and Logging에 있는 목록을 확장하자. 이 목록은 그림 6처럼 보일 것이다.


그림 6. Profiling and Logging 뷰 목록
Profiling and Logging 뷰 목록

뷰 확인을 위한 데이터 수집

문 제 해결에 더 접근하기 위해, 활성화된 하나 이상의 뷰에서 데이터를 수집할 수 있다. 이전 절에서 수집한 데이터는 단지 Memory Statistics 뷰에서 볼 수 있는 메모리 통계뿐이었다. 다시 이 뷰를 불러올 수 있다면, 그림 7과 같은 Monitoring 뷰를 볼 수 있다.


그림 7. Monitoring 뷰에서 제공하는 기본 통계
기본 통계

리 스트 최하단을 확장하면 사용하는 메모리를 위한 단순 통계 정보만을 포함한 현재 프로파일 구성을 보여준다. 가능한 많은 정보를 모을 수 있는 새로운 프로파일 구성을 생성해 보자. 이 프로파일을 통해 프로파일링과 성능 도구에서 제공하는 모든 정보를 표와 그림으로 찾아 볼 수 있다.

  1. TPTP 프로파일 버튼에 있는 작은 화살표를 클릭하고, Profile...을 선택하자.
  2. Profile 창에서 SpaceShipToy를 선택하고, 창의 왼쪽 하단에 있는 New를 클릭하자.
  3. 오른쪽 가장 자리 상단에 있는 Name 필드에 Lots of Data를 입력하고, Apply를 클릭하자.
  4. Profiling 탭을 클릭하고, Add...를 클릭하자.
  5. 다음 창에서, Profile set nameAll을, Description 필드에는 All of the data that's available을 입력하고, Next를 클릭하자.
  6. 다음 패널에서 수집하고자 하는 데이터를 선택할 수 있다. 모든 항목을 확장한 다음, 그림 8에 나오는 모든 체크 박스를 선택하자.


    그림 8. 선택한 메트릭스
    선택한 메트릭스

  7. Execution Time Analysis를 클릭하자.
  8. Collect method CPU time information 체크 박스를 선택하고, Show execution flow graphical details 옵션을 선택하자. Next를 다시 한 번 클릭하고, 그림 9처럼 다음 창에서 필요 없는 클래스들을 걸러낼 수 있다.


    그림 9. 프로파일링에서 관계없는 클래스 제외하기
    필터 창

  9. 이 예제의 목적을 위해, 새로운 필터 집합을 추가해야 하며, 이를 위해 패널의 상단에 있는 Add...를 클릭하자. 필터 이름으로 No Monkey Business를 입력하고, OK를 클릭하자.
  10. 필터 집합을 위한 새로운 규칙을 추가하기 위해 규칙의 목록 오른쪽에 있는 Add...를 클릭하자. Class name 필드에는 example.SpaceShipToy를, Method name 필드에는 main("asterisk")를 입력하고, Rule에서는 EXCLUDE를 선택하고(그림 10), OK를 클릭하자.


    그림 10. 필터 규칙 수정하기
    필터 규칙 편집

  11. 이전 큰 창에서 Apply를 클릭한다.
  12. 애플리케이션에 대한 프로파일과 수집할 정보의 표를 정의했다. 이제 Profile을 클릭하자.
  13. Profiling and Logging perspective에서 Memory Statistics 뷰를 열자. 만들었던 규칙이 적용되어 example.SpaceShipToy.main() 메서드를 제외한 실행 결과 표를 볼 수 있다.

--다음페이지--

팁과 비결

TPTP에서는 애플리케이션을 자세히 들여다 볼 수 있도록 도와주는 많은 기능을 제공한다. 그리고 TPTP가 이클립스의 일부로 자연스럽게 통합되어 이클립스의 다른 기능들과 조화롭게 엮여 있어 매우 편리하게 사용할 수 있을 것이다.

이제 몇 가지 유용한 비결을 소개하겠다.

빠른 데이터 필터

프 로파일링 세션을 시작하고, Execution Statistics 뷰를 열어 보자. 이 뷰는 애플리케이션에 있는 모든 클래스와 메서드를 보여준다(최소한 프로파일 집합에서 걸러내지 않은 것들). 그림 11 처럼 단축 메뉴를 열기 위해 뷰 화면에서 마우스 오른쪽 버튼을 클릭하자.


그림 11. 단축 메뉴
단축 메뉴

Filter out...을 클릭하고, Profiling을 선택한 다음, OK를 클릭하자. 다음 창에서(그림 12) Monkey Business를 Filter name으로 입력하고, Filter string에는 'build'를 준 다음, 그 아래에 있는 Filter by 옵션은 Method name으로 선택하자. 이제 OK 버튼을 클릭하고, 다시 한 번 OK를 누르자.


그림 12. 필터 화면 수정하기
필터 편집 창

이제 뷰는 example.SpaceShipToy$Monkey.build() 메서드에 해당하는 통계 정보만 보여줄 것이다.

다시 모든 메서드에 대한 정보를 보기 위해 본래 상태로 돌아가려면 Filter(그림 13)를 클릭하고, No filter를 선택하면 된다. 필터를 수정하기 위해서는, 같은 버튼을 클릭하고, Manage filters...를 클릭하자.


그림 13. 필터 버튼
필터 버튼



위로


소스로 이동하기

Execution Statistics 뷰에서 계속 해보자. SpaceShipToy$Booster 클래스를 더블 클릭하자. Perspective는 Java로 변경되며, 내부 클래스(inner class)인 Booster의 선언부로 즉각 이동하게 된다. Memory Analysis 뷰와 Eclipse Code Editor 사이의 연결은 개발자에게 정말 귀중한 선물이다.




위로


더 발전된 arbitrarily complex filters

Editor Filter 창의 Advanced 탭을 사용해 arbitrarily complex filters를 빌드할 수 있다. advanced filter는 규칙의 연속이며, 각 규칙은 속성(property), 상태(condition - "equal", "not equal", "like"와 같은), 값(value)의 목록을 갖고 있다. 단일 인스턴스가 어느 정도 메모리를 얼마나 소모하는지 잘 살펴 볼 필요가 있을까? 고급 필터를 사용해 보면 매우 감명받을 것이다.




위로


구성과 정렬

대부분의 데이터 뷰는 패키지, 클래스, 메서드에 의해 데이터를 구성한다. 그림 14처럼 뷰 상단에 있는 세 개 버튼 중 하나를 클릭함으로써 데이터 구성 방법을 빠르게 변경할 수 있다.


그림 14. 데이터 구성을 위한 버튼 세 개
데이터 구성을 위한 버튼 세 개

왼쪽에서 오른쪽으로 각각 패키지, 클래스, 메서드 버튼이 있고, 이 버튼에 의해 데이터를 구성할 수 있는 것을 볼 수 있다.

칼럼 제목을 클릭함으로써 모든 데이터를 정렬할 수도 있다. 일단 칼럼의 제목을 한 번 클릭하면 오름차순으로 정렬되며, 다시 한 번 같은 칼럼의 머리말을 클릭하면 데이터가 내림차순으로 정렬되는 것을 알 수 있다.



--다음페이지--



UML2 시퀀스 다이어그램을 사용해 코드 보기

TPTP 는 실행중인 애플리케이션에 대한 매우 유용한 시각화된 정보(visualization), 바로 UML2 시퀀스 다이어그램을 제공한다. 이 다이어그램은 클래스와 메서드 간의 호출 흐름을 보여줄 뿐만 아니라, 애플리케이션 실행 시간의 대부분을 소모하는 코드의 특정 부분(hot spots)만을 강조해 보여줄 수 있다.

시퀀스 다이어그램에서 코드 보기

UML2 시퀀스 다이어그램을 사용해 코드를 보기 위해서는 다음 과정을 거쳐야 한다.

  1. 프로파일링하는 장난감 공장 애플리케이션의 모든 인스턴스를 종료한다.
  2. TPTP 프로파일링 버튼에서 작은 화살표를 클릭한다. Profile...을 선택하고, SpaceShipToy를 선택한다. 그 다음 Profiling 탭을 클릭하고, All을 선택한다.
  3. (필요한 경우) Apply를 클릭하고, Profile을 클릭한다.
  4. Profiling Monitor 뷰에서 애플리케이션이 시작한 것을 확인했으면, 새로 실행된 프로세스에서 마우스 오른쪽을 클릭하고, Open With... > UML2 Thread Interactions를 선택해 UML2 class interactions 뷰를 열자. 애플리케이션이 막 시작했기 때문에, 그림 15처럼, 아직 다이어그램에는 main()을 호출한 것만 보인다.


    그림 15. main() 호출에 대한 간단한 UML 다이어그램
    main() 호출에 대한 간단한 UML 다이어그램

  5. Console 뷰로 변경하고, 메서드 호출을 좀 더 만들기 위해 애플리케이션을 조작하자. 그리고 나서 UML2 Trace Interactions 뷰로 돌아오자. UML 다이어그램 내용이 늘어났으며, 아마 그림 16과 같이 보일 것이다.


    그림 16. 예제 애플리케이션의 UML2 뷰
    좀더 확장된 UML 다이어그램

  6. 오른쪽 여백에 빨간 막대에 마우스를 올려 놓으면 CPU 시간 소모에 대한 측정계가 나타난다(그림 17).


    그림 17. CPU 소모 측정계
    CPU 소모 측정계

  7. 최대치를 가리키며 빨간색 불이 들어왔다. 예제 애플리케이션의 컨텍스트에서 SpaceShipToy 클래스의 구축이 완벽하게 병목현상에 빠졌다는 의미다.

--다음페이지--

객체 레퍼런스 분류하기

실행중인 애플리케이션을 위한 또 다른 유용한 시각화는 애플리케이션에서 각 객체 타입의 참조 개수를 보여주는 Object Reference 뷰다. 자바 코드가 과도한 양의 메모리를 사용하는 것처럼 보인다면, 객체 참조를 수집해 보여주는 이 기능을 사용해 과도하게 메모리를 쓰는 코드를 찾아내자.

Object Reference 뷰 사용하기

Object Reference 뷰는 다른 TPTP 뷰만큼이나 쉽게 사용할 수 있다.

  1. 프로파일링하고 있는 모든 프로세스를 종료하자.
  2. Profiling Monitor에서 마우스 오른쪽 버튼을 클릭하고, Unload Profiling Data를 선택하자. 여태까지 수집된 모든 데이터를 삭제하기 위해 계속 따라 해보자.
  3. 이전 화면으로 돌아가 모든 프로세스를 선택하고, Delete를 누르자. 확인을 위한 창이 뜨면, Do not delete contents를 선택하고, Yes를 클릭하자.
  4. Toy factory의 프로파일링 세션을 새로 시작하자. Console 뷰로 이동해, 두 개의 toy를 만들고 세 번째는 참조되지 않은 "toy"를 만들기 위해 1 2 9를 차례로 누르자.
  5. Profinling Monitor 뷰에서 Collect object references를 클릭함으로써 객체를 수집할 수 있다(그림 18).


    그림 18. Collect Object Reference 버튼
    Collect Object References 버튼

  6. 이클립스 도구 모음에서, Object Reference 뷰를 열기 위해 Open Object References(그림 19)를 클릭하자. Object Reference 뷰는 애플리케이션에서 사용하는 객체와 이 객체의 참조에 대한 개수의 목록을 제공한다.


    그림 19. Object Reference 버튼
    Object References 버튼

  7. SpaceShipToy 를 확장하자. 그림 20과 같은 차트를 볼 수 있다. Toy 세 개를 만들었고, 각각의 toy는 두 개의 monkey astronauts와 세 개의 states에 더해, 하나의 booster와 하나의 capsule을 포함하고 있는 것을 정확하게 말해준다.


    그림 20. 특정 시점에서 예제 애플리케이션의 객체 참조
    활성화된 객체 참조 차트
--다음페이지--

로컬 자바 애플리케이션에서 TPTP 사용하기

이 클립스 워크벤치를 통해 자바 애플리케이션 프로파일링을 구축하고, 실행하는 것 외에도 로컬 머신에서 이미 실행중인 자바 애플리케이션을 프로파일링할 수도 있다(여기서 원격 애플리케이션에 대한 프로파일을 다루지는 않지만, 원격 머신에 대한 프로파일링 또한 가능하다). TPTP를 통해 프로세스에 attach할 수도 있다. 프로세스에 어태치할 때, 여태까지 배운 메모리 할당을 찾는 방법과 메모리를 들춰 보는(peek) 도구를 모두 사용할 수 있다.

로컬 자바 애플리케이션 어태치

로컬 자바 애플리케이션을 어태치하기 위해 다음 과정을 따라 하자.

  1. Profiling Monitor 뷰에서 현재 실행중인 모든 프로세스를 종료하고, 삭제하자.
  2. 커맨드 창을 열고, JRE를 참조하는 PATHJAVA_HOME 환경 변수가 제대로 돼 있는지 확인하자.
  3. TPTP 라이브러리에 포함되어 있는 LD_LIBRARY_PATH를 확인하자. 현재 테스트 시스템에서는 다음과 같이 환경 변수 값을 확인할 수 있었다(여러분이 사용하는 경로 이름과 디렉터리 이름은 다를 수 있으며, 이 변수는 시스템 환경에 종속된다).
    % printenv
    .
    PATH=/bin:/usr/bin:/usr/X11R6/bin:/home/\
    mstreicher/java/jdk/bin
    JAVA_HOME=/home/mstreicher/java/jdk
    JAVA_DIR=/home/mstreicher/java
    LD_LIBRARY_PATH=/home/mstreicher/java/tptpd/lib:

  4. TPTP 에이전트 컨트롤러가 현재 실행중인지 확인하자. 에이전트 컨트롤러가 포함되어 있는 디렉터리로 이동한 다음, 데몬을 중지하고 다시 시작하자.
    % cd $JAVA_DIR/tptpd/bin
    % ./RAStop.sh
    RAServer stopped, pid = 3163
    RAServer stopped, pid = 3164
    .
    RAServer stopped, pid = 18108
    % ./RAStart.sh
    Starting Agent Controller
    RAServer started successfully

  5. 각각의 factory 애플리케이션을 별도의 독립적인 자바 애플리케이션으로 실행하자.
    • 예제 애플리케이션을 포함하고 있는 작업 디렉터리로 변경하자. 아마도 $HOME/workspace/ToyMaker일 것이다. 이 디렉터리 내에 SpaceShipToy.java와 이 자바 파일의 .class 파일을 포함하고 있는 example이란 이름의 디렉터리가 보일 것이다.
    • 현재 작업 디렉터리에서, CLASSPATH.("점", dot)을 추가하자.
      % cd $HOME/workspace/Toy Maker
      % ls -F
      example
      % export CLASSPATH=.:$CLASSPATH

  6. -XrunpiAgent:server=enabled 옵션을 추가해서 TPTP 에이전트 컨트롤러를 사용해 애플리케이션을 실행하자. enabled 모드에서는 자바 애플리케이션이 일반적으로 시작되고, 컨트롤러가 백그라운드에서 실행된다(어태치될 때까지 애플리케이션이 실행되지 않는 것을 선호한다면, controlled 모드를 사용하라).
    % java -XrunpiAgent:server=enabled example/SpaceShipToy

  7. 이클립스를 실행하고, TPTP Profile 버튼에 있는 작은 화살표를 클릭하자. 왼쪽 리스트에 있는 Profile...을 선택하고, Attach - Java Process를 더블 클릭하자.
  8. 다음 화면에서 Name 필드에 Toys를 입력하고, host로는 localhost를 선택하자. 다음으로 Apply를 클릭하자.
  9. 그림 21처럼, Agents 탭을 클릭해 agent를 선택하자.


    그림 21. 어태치를 위한 agent 선택하기
    어태치를 위한 에이전트 선택


    화면에 나온 agent를 클릭한 다음(다른 애플리케이션이나 프로세스가 프로파일링되지 않는다면, 적어도 지금은 agent가 하나뿐일 것이다) > 를 클릭하자. 변경 사항을 저장하기 위해 Apply를 다시 클릭하자.

  10. Profiling 탭을 선택하고, Profiling set을 지정함으로써 우리가 수집하길 원하는 데이터를 선택하자. All을 선택할 수도 있고, 이전에 만들었던 것 중에서 선택할 수도 있다.
  11. Apply를 클릭한 다음, Profile을 클릭하자. 이클립스는 Profiling and Logging perspective로 perspective를 변경할 것이다.
  12. 대부분의 시스템에서는 그림 22처럼 창이 뜰 것이다.


    프로파일링 리마인더
    프로파일링 리마인더


    이 경고는 일반적이며, 프로세스에 어태치하기는 했지만, 사용할 때는 반드시 모니터링을 수동으로 해야 한다고 상기시켜 주는 역할을 한다. 모니터링을 시작하기 위해서는 새로 실행된 프로파일 프로세스에서 마우스 오른쪽 버튼을 클릭하고, Start monitoring을 선택하자.

  13. 커맨드 창으로 돌아와 애플리케이션을 다뤄보자. 다시 실행중인 애플리케이션을 살펴보기 위해 이클립스로 돌아가자. 애플리케이션을 종료할 때는, Terminate Process 버튼을 클릭하자(그림 23).


    그림 23. Terminate Process 버튼
    Terminate Process 버튼


    해당 프로세스가 커맨드 창에서 삭제되는 것을 볼 수 있다.

    % java -XrunpiAgent:server=enabled example/SpaceShipToy
    .
    Stage complete.
    Start stage...
    Stage complete.
    Start stage...
    Stage complete.
    zsh: killed java -XrunpiAgent:server=enabled example/SpaceShipToy
    %

--다음페이지--

결론

이 튜토리얼은 프로파일링을 통해 자바 애플리케이션을 다듬고, 발전시킬 수 있는 방법을 설명하고 있다. 이클립스 TPTP를 사용해 코드를 실행할 수 있고, 메모리가 허비되고, 성능이 떨어지는 원인이 되는 부분을 찾을 수 있다. TPTP는 많은 로그 파일과 테스트 결과를 분석하고, 자동화를 통합해주는 도구 또한 제공한다.

TPTP에는 몇 가지 추가 도구가 있다. 대표적인 것으로는 이클립스에서 실행중인 애플리케이션의 GUI를 테스트하기 위한 편리한 녹화-재생 도구와 이클립스 기반 애플리케이션을 프로파일링하기 위해 특별히 디자인된 테스트를 포함하는 XRay가 있다.

기사의 원문보기


참고자료

교육

제품 및 기술 얻기

토론

필자소개


Martin Streicher는 Linux Magazine 편집장이다. 그는 퍼듀 대학에서 컴퓨터 과학 석사 학위를 받았으며, 1982년부터 파스칼, C, 펄, 자바와 최근에는 루비 프로그래밍 언어로 유닉스 계열 시스템을 프로그래밍해 왔다.