자바 어플리케이션의 성능과 관련된 문제를 해결하거나 CPU와 메모리의 사용량과 관련된 모니터링을 위해서 가장 쉽게 접근할 수 있는 툴은 VisualVM일 것이다. 오늘은 Java VisualVM의 Sampler와 Profiler를 보는 법에 대해서 간략히 정리하고자 한다.
Sampler와 Profiler 모두 자바 어플리케이션의 CPU와 메모리 사용량을 분석하는 툴이지만 그 동작 방식에서는 차이를 보인다.
Sampling
샘플링은 주기적(20 ms ~ 10000 ms)으로 메소드 콜 정보(스레드 덤프 사용)와 메모리 사용 정보를 스냅샷하고 그 결과를 분석하여 메서드 별 혹은 스레드 별 CPU 실행 시간을 수집하는 것을 말한다. 그렇기 때문에 정확한 분석은 아니지만 분석 대상 어플리케이션의 성능에 큰 영향을 주지 않는다.
Profiling
프로파일링은 메소드별 CPU 실행 시간을 분석하기 위해 함수의 진입과 진출부에 바이트 코드를 삽입하여 정확한 통계를 집계한다. 그래서, 프로파일러를 실행해 보면 셋업 과정에서도 약간의 시간이 소요되며, 실행되는 과정에서도 분석 대상 어플리케이션의 성능에 영향을 미친다.
Sampler vs Profiler
Sampler와 Profiler의 차이점을 표로 정리하였다.
Sampler | Profiler | |
동작 방식 | 주기적(20 ms ~ 10000 ms) 스레드 덤프 결과 분석 | 메소드 진입부와 진출부에 통계 수집 코드 삽입 |
정확도 | Approximated. 하지만, Profiler와 비슷한 양상으로 관측 됨. | Precise |
수집 결과 | 각 메소드별 CPU 실행 시간, 각 스레드별 CPU 실행 시간 |
각 메소드별 CPU 실행 시간 |
수집시 어플리케이션에 미치는 영향 | 적음 | 큼 |
제약 사항 | JIT 컴파일러에 의해 실행 시간에 Inline Call로 호출되는 메소드에 대해서는 정확한 수집이 되지 않음. |
Sampler와 Profiler의 GUI
VisualVM을 한번이라도 사용해 보았다면 사용자 인터페이스는 크게 어려운 것이 없다는 것을 알고 있을 것이다. 하지만, Sampler와 Profiler를 사용할 때, '샘플링 대상 패키지' 혹은 '샘플링 제외 패키지' 옵션을 잘 명시하여 원하는 메서드와 메모리 영역을 모니터링 하자.
VisualVM의 CPU/메모리를 위한 Sampler와 Profiler 각각을 위한 사용자 인터페이스는 위의 [그림 1]과 대부분 동일하다. 다만, '샘플링 결과' 테이블에 표시되는 정보만 다를 뿐이다. 아래에서는 CPU의 Sampler와 Profiler, Memory Sampler와 Profiler 순서대로 '결과' 테이블의 각 필드가 어떤 의미를 가지는지 분석해 보도록 하겠다.
CPU Sampler의 CPU Samples 탭
샘플링을 시작한 이후에 호출되는 메소드들의 실행 시간에 대한 정보를 샘플링하여 정보를 출력한다.
항목 | 설명 |
Hot Spots - Method | 메소드의 이름 (패키지명 포함) |
Self Time [%] | 메소드의 실행 시간이 전체 메소드의 실행 시간에서 몇 퍼센트를 차지하는지 표현하는데 두 가지 방식으로 동작한다. 첫 번째, 'Self Time' 항목을 기준으로 정렬할 경우(즉, Self Time 컬럼의 헤드를 클릭할 경우), 'Self Time'을 기준으로 비율을 계산한다. 두 번째, 'Self Time (CPU)' 항목을 기준으로 정렬할 경우(즉, Self Time(CPU) 컬럼의 헤드를 클릭할 경우), 'Self Time (CPU)'를 기준으로 비율을 계산한다. |
Self Time | 메소드의 실행 시간이며, 해당 메소드 내부에서 호출한 메소드의 실행 시간은 포함되지 않는다. |
Self Time (CPU) | 메소드가 실제 CPU를 사용한 시간이며, 해당 메소드 내부에서 호출한 메소드의 CPU 실행 시간은 포함되지 않는다. 당연히 Lock이나 Sleep, IO로 인한 대기시간은 포함되지 않는다. |
Total Time | 메소드의 총 실행 시간이며 내부에서 호출하는 메소드의 실행시간까지 포함한다. 메소드를 호출할 경우 해당 스레드의 스택 프레임이 생성되는데 해당 스택 프레임이 존재하는 시간을 의미한다. |
Total Time (CPU) | 'Self Time (CPU)'에 추가로 해당 함수의 내부에서 호출하는 함수의 CPU 실행까지 포함한다. |
Samples | 샘플링을 할때마다 발견된 횟수. 이 항목은 기본 상태에서는 보이지 않고, 테이블의 가장 오른쪽 '창' 모양 아이콘을 클릭하여 표시 가능 함. |
CPU Sampler의 Thread CPU Time 탭
샘플링을 시작한 이후에 각 스레드별로 CPU를 사용하는 시간에 대한 샘플링 정보를 출력한다.
항목 | 설명 |
Thread Name | 스레드 이름 |
Thread CPU Time [%] | 해당 스레드의 CPU 사용시간이 전체 스레드의 CPU 사용시간 총 합에서 차지하는 비중. |
Thread CPU Time [ms] | 스레드가 사용한 CPU의 누적 실행 시간(ms) |
Thread CPU Time [ms]/sec | 스레드가 1초마다 사용하는 CPU 실행 시간(ms). 값이 1000에 가까울수록 Busy한 것이고, 0에 가까울수록 Idle일 것이다. |
CPU Profiler
프로파일링을 시작한 이후에 발생하는 메서드 별 실행 시간에 대한 정보를 출력한다.
항목 | 설명 |
Hot Spots - Method | 메소드 이름 (패키지명 포함) |
Self Time [%] | 자신의 Self Time이 전체 Self Time에서 차지하는 비중. |
Self Time | 메소드의 실행 시간이며, 해당 메소드 내부에서 호출한 메소드의 실행 시간은 포함되지 않는다. |
Total Time | 메소드의 총 실행 시간이며 내부에서 호출하는 메소드의 실행시간까지 포함한다. 메소드를 호출할 경우 해당 스레드의 스택 프레임이 생성되는데 해당 스택 프레임이 존재하는 시간을 의미한다. |
Invocations | 메소드가 호출된 횟수 |
Memory Sampler의 Heap histogram 탭
항목 | 설명 |
Class Name | 클래스 이름 |
Bytes [%] | 전체 'Bytes' 에서 해당 클래스 인스턴스의 'Bytes'가 차지하는 비율 |
Bytes | 메모리 사용량 |
Instances | 인스턴스 개수 |
Memory Sampler의 Per thread allocations 탭
항목 | 설명 |
Thread Name | 쓰레드 이름 |
Allocated Bytes [%] | 스레드에 할당된 메모리가 전체 메모리에서 차지하는 비율 |
Allocated Bytes | 스레드에 할당된 메모리 |
Allocated Bytes/sec | 스레드에 초당 할당되는 메모리 |
Memory Profiler
항목 | 설명 |
Class Name - Live Allocated Objects | 클래스 이름 |
Live Bytes [%] | 'Live Bytes' 총 합에서 차지하는 비중 |
Live Bytes | Gabage Collector에 의해 회수되지 않은 오브젝트의 메모리 사용량(Bytes)이며 Unreachable 오브젝트를 포함 할 수 있다. |
Live Objects | Garbage Collector에 의해 회수되지 않는 전체 오브젝트 개수이며, Unreachable 오브젝트를 포함 할 수 있다. |
Allocated Objects | 어플리케이션이 시작되고 나서부터 생성된 인스턴스의 개수('Rest Collected Results Buffer'를 사용하여 리셋할 경우 초기화 됨) |
Avg. Age | Gabage Collection을 수행했을 경우 살아 남은 횟수를 Age로 표현하는데, 그 평균 값을 의미한다. Generational Gabaga Collection 알고리즘의 경우 Young과 Old를 구분하지 않는다. |
Generations | 객체의 인스턴스를 포함하고 있는 Generation의 개수를 의미 함. |
특정 클래스의 메모리 사용량을 글래프로 보고 싶은 경우, Memory Profiler의 결과 창에서 원하는 클래스에 마우스 '우클릭'을 하게 되면 'Log Class History'라는 메뉴를 선택할 수 있다. 특정 클래스의 Live Objects, Live Bytes, Allocated Objects의 시간에 따른 변화를 관찰할 수 있다.
댓글