CPU 프로파일러의 트레이스 뷰에서는 기록된 트레이스의 정보를 몇 가지 방법으로 볼 수 있습니다.
메서드 트레이스와 함수 트레이스의 경우 Threads 타임라인에서 직접 Call Chart를 볼 수 있고 Analysis 창에서 Flame Chart, Top Down, Bottom Up, Events 탭을 볼 수 있습니다. 호출 스택 프레임의 경우 실행된 코드 부분과 이 부분이 호출된 이유를 볼 수 있습니다. 시스템 트레이스의 경우 Threads 타임라인에서 직접 Trace Events를 볼 수 있고 Analysis 창에서 Flame Chart, Top Down, Bottom Up, Events 탭을 볼 수 있습니다.
마우스 및 단축키를 사용하여 더 쉽게 Call Charts나 Trace Events를 탐색할 수 있습니다.
호출 차트를 사용하여 트레이스 검사
Call Chart에서는 메서드 트레이스 또는 함수 트레이스가 그래픽으로 표시됩니다. 가로축에는 호출의 기간과 타이밍이 표시되고 세로축에는 피호출자가 표시됩니다. 시스템 API 호출은 주황색으로 표시되고, 앱 자체의 메서드 호출은 녹색으로 표시되고, 서드 파티 API(자바 언어 API 포함) 호출은 파란색으로 표시됩니다. 그림 4에 호출 차트의 예 및 주어진 메서드 또는 함수의 Self 시간, Children 시간, Total 시간의 개념이 나와 있습니다. Top Down 및 Bottom Up을 사용하여 트레이스를 검사하는 방법에 관한 섹션에서 이 개념을 자세히 알아볼 수 있습니다.
그림 1. 메서드 D의 Self 시간, Children 시간, Total 시간을 보여주는 호출 차트의 예
팁: 메서드 또는 함수의 소스 코드로 건너뛰려면 메서드 또는 함수를 마우스 오른쪽 버튼으로 클릭하고 Jump to Source를 선택하세요. 이 기능은 Analysis 창의 어느 탭에서나 작동합니다.
Flame Chart 탭을 사용하여 트레이스 검사
Flame Chart 탭에는 동일한 호출 스택을 집계하는 반전 호출 차트가 표시됩니다. 즉, 같은 호출자 순서를 공유하는 동일한 메서드 또는 함수가 수집되어 Flame Chart에 (호출 차트에 표시된 것처럼 짧은 막대 여러 개가 아니라) 긴 막대 하나로 표시됩니다. 따라서 어느 메서드 또는 함수가 가장 많은 시간을 소비하는지 더 쉽게 확인할 수 있습니다. 하지만 가로축은 타임라인을 표시하지 않으며 대신 각 메서드 또는 함수가 실행되는 데 걸리는 상대적인 시간을 나타냅니다.
이 개념을 알아보기 위해 그림 2의 호출 차트를 살펴보세요. 메서드 D는 B를 여러 번 호출하며(B1, B2, B3) 그중 일부는 C를 호출합니다(C1 및 C3).
그림 2. 여러 메서드 호출에서 공통된 호출자 순서를 공유하는 호출 차트
B1, B2, B3은 동일한 호출자 순서(A → D → B)를 공유하므로 그림 3과 같이 집계됩니다. 마찬가지로 C1과 C3도 동일한 호출자 순서(A → D → B → C)를 공유하므로 집계됩니다. C2는 호출자 순서(A → D → C)가 다르기 때문에 포함되지 않습니다.
그림 3. 같은 호출 스택을 공유하는 동일한 메서드 집계
집계된 호출은 그림 4에 표시된 것과 같은 Flame Chart를 만드는 데 사용됩니다. Flame Chart의 각 호출에 관해 CPU 시간을 가장 많이 소비하는 피호출자가 먼저 표시됩니다.
그림 4. 그림 5에 표시된 호출 차트를 표현한 Flame Chart
Top Down 및 Bottom Up을 사용하여 트레이스 검사
Top Down 탭에는 메서드 또는 함수 노드를 확장하면 피호출자가 표시되는 호출 목록이 표시됩니다. 그림 5에는 그림 1의 호출 차트에 관한 하향식 그래프가 표시되어 있습니다. 그래프의 각 화살표가 호출자에서 피호출자를 가리킵니다.
그림 5와 같이 Top Down 탭에서 메서드 A의 노드를 확장하면 피호출자인 메서드 B와 D가 표시됩니다. 그런 다음 메서드 D의 노드를 확장하면 피호출자인 메서드 B와 C 등이 노출됩니다. Flame Chart 탭과 마찬가지로 하향식 트리는 같은 호출 스택을 공유하는 동일한 메서드의 트레이스 정보를 집계합니다. 즉, Flame Chart 탭에는 Top down 탭이 그래픽으로 표시됩니다.
Top Down 탭에는 각 호출에 사용된 CPU 시간을 설명하는 데 도움이 되는 다음과 같은 정보가 표시됩니다(시간은 선택된 범위에 대한 스레드의 총 시간의 비율로도 표시됨).
- Self: 그림 1에 메서드 D에 관해 표시된 대로, 메서드 또는 함수 호출에서 피호출자의 코드가 아니라 자체 코드를 실행하는 데 사용한 시간.
- Children: 그림 1에 메서드 D에 관해 표시된 대로, 메서드 또는 함수 호출에서 자체 코드가 아니라 피호출자를 실행하는 데 사용한 시간.
- Total: 메서드의 Self 및 Children 시간의 합. 그림 1에 메서드 D에 관해 표시된 대로, 앱에서 호출을 실행하는 데 사용된 총 시간을 나타냅니다.

그림 5. Top Down 트리

그림 6. 그림 5의 메서드 C에 관한 Bottom Up 트리
Bottom Up 탭에는 메서드 또는 함수 노드를 확장하면 호출자가 표시되는 호출 목록이 표시됩니다. 그림 6은 그림 5의 트레이스 예를 사용하여 메서드 C의 상향식 트리를 제공합니다. 상향식 트리에서 메서드 C의 노드를 열면 고유한 호출자인 메서드 B와 D가 각각 표시됩니다. B가 C를 두 번 호출하지만 B는 상향식 트리에서 메서드 C의 노드를 확장할 때 한 번만 표시됩니다. 그런 다음 B의 노드를 확장하면 B의 호출자인 메서드 A와 D가 표시됩니다.
Bottom Up 탭은 CPU 시간을 가장 많이(또는 가장 적게) 소비하는 메서드 또는 함수를 정렬하는 데 유용합니다. 각 노드를 검사하여 어느 호출자가 메서드 또는 함수를 호출하기 위해 CPU 시간을 가장 많이 사용하는지 확인할 수 있습니다. 하향식 트리와 비교하여, 상향식 트리에 있는 각 메서드 또는 함수의 타이밍 정보는 각 트리의 상단에 있는 메서드(최상위 노드)에 관한 것입니다. CPU 시간은 기록 중 스레드의 총 시간의 비율로도 표시됩니다. 다음 표에서는 최상위 노드 및 그 호출자(하위 노드)의 타이밍 정보를 해석하는 방법을 설명합니다.
Self | Children | 합계 | |
---|---|---|---|
상향식 트리의 상단에 있는 메서드 또는 함수(최상위 노드) | 메서드 또는 함수에서 피호출자의 코드가 아니라 자체 코드를 실행하는 데 사용된 총 시간을 나타냅니다. 하향식 트리와 비교하여, 이 타이밍 정보는 기록 기간에 이 메서드 또는 함수의 모든 호출의 합을 나타냅니다. | 메서드 또는 함수에서 자체 코드가 아니라 피호출자를 실행하는 데 사용된 총 시간을 나타냅니다. 하향식 트리와 비교하여, 이 타이밍 정보는 기록 기간에 이 메서드 또는 함수의 피호출자의 모든 호출의 합을 나타냅니다. | Self 시간과 Children 시간의 합 |
호출자(하위 노드) | 호출자에 의해 호출될 때 피호출자의 총 Self 시간을 나타냅니다. 예를 들어, 그림 6의 상향식 트리에서 메서드 B의 Self 시간은 B에 의해 호출될 때 메서드 C의 각 실행에 관한 Self 시간의 합과 같습니다. | 호출자에 의해 호출될 때 피호출자의 총 Children 시간을 나타냅니다. 예를 들어, 그림 6의 상향식 트리에서 메서드 B의 Children 시간은 B에 의해 호출될 때 메서드 C의 각 실행에 관한 Children 시간의 합과 같습니다. | Self 시간과 Children 시간의 합 |
참고: 주어진 기록에 관해 프로파일러가 파일 크기 한도에 도달하면 Android 스튜디오에서 새로운 데이터 수집을 중지합니다(하지만 기록이 중단되지는 않습니다). 계측된 트레이스에서는 샘플링된 트레이스보다 짧은 기간에 더 많은 데이터를 수집하므로 계측된 트레이스를 수행하면 보통 이런 상황이 훨씬 더 빠르게 발생합니다. 검사 시간을 한도에 도달한 후 발생한 기록 기간으로 확장해도 사용 가능한 새로운 데이터가 없으므로 트레이스 창의 타이밍 데이터가 변경되지 않습니다. 또한 사용 가능한 데이터가 없는 기록 부분만 선택하는 경우 트레이스 창에 타이밍 정보로 NaN이 표시됩니다.
이벤트 테이블을 사용하여 트레이스 검사
이벤트 테이블에는 현재 선택된 스레드의 모든 호출이 나열됩니다. 열 헤더를 클릭하여 정렬할 수 있습니다. 테이블의 행을 선택하여 선택된 호출의 시작 시간과 종료 시간으로 타임라인을 이동할 수 있습니다. 이를 통해 타임라인에서 이벤트를 정확하게 찾을 수 있습니다.
그림 7. Analysis 창에서 Events 탭 보기
호출 스택 프레임 검사
호출 스택은 코드의 어느 부분이 실행되었고 호출된 이유가 무엇인지 파악할 때 유용합니다. 자바/Kotlin 프로그램을 위해 호출 스택 샘플 기록이 수집되는 경우 호출 스택은 일반적으로 자바/Kotlin 코드뿐 아니라 JNI 네이티브 코드, 자바 가상 머신(예:
android::AndroidRuntime::start
), 시스템 커널([kernel.kallsyms]+offset
)의 프레임도 포함합니다. 자바/Kotlin 프로그램이 일반적으로 자바 가상 머신을 통해 실행되기 때문입니다. 프로그램 자체가 실행되고 프로그램이 시스템 및 하드웨어와 통신하려면 네이티브 코드가 필요합니다. 프로파일러는 정밀도를 위해 이러한 프레임을 표시합니다. 그러나 사용자의 조사에 따라 이러한 추가 호출 프레임이 유용할 수도, 유용하지 않을 수도 있습니다. 프로파일러는 관심 없는 프레임을 축소하여 조사와 관련 없는 정보를 숨길 방법을 제공합니다.
아래 예에서 아래쪽의 트레이스에는 [kernel.kallsyms]+offset
이라고 지정된 프레임이 여러 개 있는데, 이러한 프레임은 현재 개발에 유용하지 않습니다.
이러한 프레임을 하나로 축소하려면 툴바에서 프레임 축소 버튼을 선택하고 축소할 경로를 선택한 다음 적용 버튼을 선택하여 변경사항을 적용합니다. 이 예에서 경로는 [kernel.kallsyms]
입니다.
이렇게 하면 아래와 같이 왼쪽 및 오른쪽 패널에서 선택한 경로에 해당하는 프레임이 축소됩니다.
시스템 트레이스 검사
시스템 트레이스를 검사할 때 Threads 타임라인에서 Trace Events를 검사하여 각 스레드에 발생한 이벤트의 세부정보를 확인할 수 있습니다. 이벤트에 마우스 포인터를 가져가면 이벤트 이름과 각 상태에 소요된 시간을 확인할 수 있습니다. 이벤트를 클릭하면 Analysis 창에서 자세한 정보를 볼 수 있습니다.
시스템 트레이스 검사: CPU 코어
CPU 예약 데이터 외에도 시스템 트레이스에는 코어별 CPU 주파수가 포함됩니다. 이를 통해 각 코어의 활동량을 확인할 수 있으며, 최신 모바일 프로세서에서 어떤 코어가 '빅' 코어인지 '리틀' 코어인지 파악할 수 있습니다.
그림 8. 렌더링 스레드의 CPU 활동 및 트레이스 이벤트 보기
CPU Cores 창(그림 8 참고)에는 모든 코어에 예약된 스레드 활동이 표시됩니다. 스레드 활동에 마우스 포인터를 가져가면 코어가 특정 시점에 실행 중인 스레드를 확인할 수 있습니다.
시스템 트레이스 정보 검사에 관한 자세한 내용은 systrace
문서의 UI 성능 문제 조사 섹션을 참고하세요.
시스템 트레이스 검사: 프레임 렌더링 타임라인
앱이 기본 스레드 및 RenderThread
에서 각 프레임을 렌더링하는 데 걸리는 시간을 검사하여 UI 버벅거림 및 프레임 속도 저하를 유발하는 병목 현상을 조사할 수 있습니다. 시스템 트레이스를 사용하여 조사하고 UI 버벅거림을 줄이는 방법을 자세히 알아보려면 UI 버벅거림 감지를 참조하세요.
시스템 트레이스 검사: 프로세스 메모리(RSS)
Android 9 이상을 실행하는 기기에 배포된 앱의 경우 Process Memory(RSS) 섹션에는 앱에서 현재 사용 중인 실제 메모리의 양이 표시됩니다.
그림 9. 프로파일러에서 실제 메모리 보기
Total
프로세스에서 현재 사용 중인 실제 메모리의 총량입니다. Unix 기반 시스템에서는 이를 'Resident Set Size'라고 하며 익명 할당과 파일 매핑, 공유 메모리 할당에 사용된 모든 메모리의 조합입니다.
Windows 개발자의 경우 Resident Set Size는 작업 집합 크기와 유사합니다.
Allocated
이 카운터는 프로세스의 일반 메모리 할당에 현재 사용되는 실제 메모리의 양을 추적합니다. 이는 익명(특정 파일이 지원하지 않음) 및 비공개(공유되지 않음)인 할당을 의미합니다. 대부분의 애플리케이션에서는 힙 할당(malloc
또는 new
사용)과 스택 메모리로 구성됩니다. 실제 메모리에서 교체되면 이러한 할당은 시스템 스왑 파일에 작성됩니다.
File Mappings
이 카운터는 프로세스가 파일 매핑에 사용하는 실제 메모리의 양을 추적합니다. 즉, 메모리 관리자가 파일에서 메모리 영역으로 매핑한 메모리입니다.
Shared
이 카운터는 이 프로세스와 시스템의 다른 프로세스 간에 메모리를 공유하는 데 사용 중인 실제 메모리의 양을 추적합니다.