 |  |
|
자바 애플리케이션 프로파일링
이제 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를 사용하는 과정은 다음과 같다.
- 에이전트 컨트롤러 실행
- 에이전트 컨트롤러의 bin 디렉터리로 변경하고, RAStart.sh 실행
% cd $JAVA_DIR/tptpd/bin
% ./RAStart.sh
|
- 이클립스에서 워크벤치로 이동한 다음, File > New > Project를 클릭해 새로운 자바 프로젝트를 생성하자. Options 목록에서 Java Project를 선택하고 Next를 클릭한다.
- 다음 창에서 프로젝트 이름을
Toy Maker로 주고, Finish를 클릭하자. 새로운 프로젝트의 이름인 "Toy Maker"는 Package Explore 패널에서 확인할 수 있다.
-
example 패키지 안에 SpaceShipToy라는 새로운 자바 클래스를 만들자. File > New > Class를 클릭하자.
- 다음으로 나오는 창에서 Package 필드에는
example을 넣고, Name 필드에는 SpaceShipToy를 입력하자. 이 창에서 다른 값은 설정하지 않는다.
-
Finish를 클릭하자. 이제 새로 생성한 클래스의 구조(skeleton)를 확인할 수 있다.
- 이클립스 클래스 편집기에 Listing 1에 나왔던 코드를 붙여 넣는다. 비어 있는 클래스 정의 부분은 변경됐지만,
package example 선언이 남아 있는지 확인하자. 코드를 저장해 변경 사항을 적용하면 이클립스가 새 버전의 클래스를 자동으로 다시 컴파일한다.
- 애플리케이션을 실행하고 싶은 경우, Run > Run...을 클릭하고, Java Application을 더블 클릭한 다음, SpaceShipToy를 선택한 후, Run을 클릭하자. 애플리케이션의 작동을 확인하기 위해 Windows > Show View...를 클릭하고, Console을 선택하자.
-
1(숫자 1)을 입력하고 Return을 누르자. 화면이 그림 2처럼 보일 것이다.
그림 2. 이클립스에서 실행되는 장난감 공장
동일 애플리케이션 프로파일링
위에서 다룬 똑 같은 애플리케이션을 프로파일링하는 과정은 다음과 같다.
- TPTP Profile을 클릭한 다음, Profile...을 선택하자.
- SpaceShipToy을 다시 보기 위해 Java Application을 확장하자. Profile 창은 Run을 클릭했을 때 나타나는 Run 창과 비슷하지만, Profile이라는 추가 탭이 있다.
- 프로파일러 내에서 애플리케이션을 시작하기 위해 Profile을 클릭하자. Perspective가 자동으로 변경되지 않으면, Window > Open Perspective > Other...를 클릭한 다음 Profiling and Logging을 선택하자.
- Profiling과 Logging perspective가 나타났을 때, Profiling Monitor 뷰의 내용을 확장하고,
<monitoring>으로 시작하는 줄을 선택하자. 이 줄을 선택했을 때, Console 뷰가 나타난다.
-
0, 1, 2와 9를 입력하자. 화면에 그림 3과 같은 내용이 나온다.
그림 3. 실행중인 애플리케이션의 Profiling과 Logging perspective
- Memory Statistics 뷰를 클릭하고,
example 패키지와 관련된 줄을 확장하자. 이 뷰는 그림 4와 같다. 각 객체는 4개의 인스턴스(장난감을 "만들기" 위한 세 개와 참조되지 않은 장난감 하나의 인스턴스)를 갖고 있다.
그림 4. 세 개의 toy 오브젝트와 하나의 참조되지 않은 toy 오브젝트가 빌드된 후 메모리 소모 내역
Memory Statistics 뷰에 있는 칼럼은 인스턴스와 사용하고 있는 메모리 통계를 추적해 준다.
-
Total Instances는 클래스의 총 인스턴스 개수를 반영한다.
-
Live Instances는 얼마나 많은 인스턴스가 계속 참조되고 있고, 가비지 컬렉터에 의해 수집되지 않았는지 보여준다.
-
Collected는 얼마나 많은 클래스의 인스턴스를 가비지 컬렉터가 수집했는지 보여준다.
-
Total Size (bytes)와 Active Size (bytes)는 모든 인스턴스가 사용하고 있는 누적된 총 메모리 양과 현재 존재하는 인스턴스에 의해 실제로 사용되는 메모리 양을 각각 보여준다.
시험 실행 끝내기
이번 시험 실행을 끝마치려면 Console 뷰를 뒤로 넘기고 0, 1과 2 숫자 키를 다시 누른다. 가비지 컬렉션 을 강제로 하기 위해 Monitoring 뷰에 있는 trash 아이콘을 클릭하자. 가비지 컬렉션이 완벽하게 수행됐다면 참조되지 않은 모든 객체를 수집해 간다. 언제든지 Refresh(그림 5)를 클릭함으로써, 현재 Perspective에 있는 모든 뷰를 새로 고칠 수 있다.
그림 5. Refresh 버튼
|  |