Java/Kotlin 할당을 기록하면 성능 문제를 일으킬 수 있는 바람직하지 않은 메모리 패턴을 식별하는 데 도움이 됩니다. 프로파일러는 객체 할당에 관한 다음 정보를 표시할 수 있습니다.
- 할당된 객체의 유형 및 할당된 객체가 사용하는 공간의 크기
- 각 할당의 스택 트레이스(할당이 들어 있는 스레드 포함)
- 객체가 할당 해제된 시간입니다.
정상적인 사용자 상호작용과 극단적인 사용자 상호작용 중에 메모리 할당을 기록하여 코드에서 단기간에 너무 많은 객체를 할당하거나 누출되는 객체를 할당하는 부분을 정확히 파악해야 합니다. 앱 메모리를 프로파일링해야 하는 이유 자세히 알아보기
Java/Kotlin 할당을 기록하는 방법
Java/Kotlin 할당을 기록하려면 프로파일러 Home 탭에서 Track Memory Consumption (Java/Kotlin Allocations) 작업을 선택합니다. Java/Kotlin 할당을 기록하려면 디버그 가능 앱(프로파일러: 'app'을 디버그 가능으로 실행 (전체 데이터) 사용)이 필요합니다.
Android 스튜디오는 기본적으로 메모리의 모든 객체 할당을 캡처합니다. 앱에서 많은 객체를 할당하는 경우 프로파일링하는 동안 앱이 눈에 띄게 느려질 수 있습니다. 프로파일링하는 동안 성능을 개선하려면 할당 추적 드롭다운으로 이동하여 전체 대신 샘플링됨을 선택합니다. 샘플링 시 프로파일러는 일정한 간격으로 메모리에서 객체 할당을 수집합니다.
녹화 중에 가비지 컬렉션 이벤트를 강제 실행하려면 쓰레기통 아이콘 을 클릭합니다.
Java/Kotlin 할당 개요
녹화를 중지하면 다음이 표시됩니다.
- 이벤트 타임라인에는 활동 상태, 사용자 입력 이벤트, 화면 회전 이벤트가 표시됩니다.
- 메모리 사용 타임라인에는 다음 정보가 표시됩니다. 타임라인의 일부를 선택하여 특정 시간 범위로 필터링할 수 있습니다.
- 메모리 카테고리별 메모리 사용량의 누적 그래프. 메모리 사용량은 왼쪽의 y축과 상단의 색상 키로 표시됩니다.
- 할당된 객체의 수를 나타내는 파선. 객체 수는 오른쪽의 y축에 표시됩니다.
- 각 가비지 컬렉션 이벤트의 아이콘.
- 표 탭에는 클래스 목록이 표시됩니다. Total Count는 선택한 기간의 끝에 있는 할당 수 (Allocations에서 Deallocations를 뺀 값)이므로 Total Count 값이 가장 높은 클래스를 먼저 디버그하는 것이 좋습니다. 선택한 기간의 최대 할당량을 기준으로 클래스 문제를 해결하는 데 관심이 있다면 할당량을 기준으로 우선순위를 지정하세요. 마찬가지로 Remaining Size는 Allocations Size에서 Deallocations Size를 뺀 값(바이트)입니다.
- 표 목록에서 클래스를 클릭하면 할당된 시간, 할당 해제된 시간, 얕은 크기 등 연결된 객체 목록이 포함된 인스턴스 창이 열립니다.
시각화 탭에는 선택한 기간 동안 호출 스택에 있는 모든 객체의 집계된 보기가 표시됩니다. 기본적으로 인스턴스가 표시된 호출 스택이 차지하는 총 메모리 양을 보여줍니다. 첫 번째 행에는 스레드 이름이 표시됩니다. 기본적으로 객체는 할당 크기에 따라 왼쪽에서 오른쪽으로 쌓입니다. 드롭다운을 사용하여 순서를 변경하세요.
힙 드롭다운을 사용하여 특정 힙으로 필터링합니다. 힙 덤프를 캡처할 때 사용할 수 있는 필터 외에도 Java 네이티브 인터페이스 (JNI) 참조가 할당되고 해제되는 위치를 보여주는 힙인 JNI 힙의 클래스를 필터링할 수 있습니다.
정렬 드롭다운을 사용하여 할당을 정렬할 방법을 선택합니다. 힙 덤프를 캡처할 때 사용할 수 있는 정렬 외에도 호출 스택별로 정렬할 수 있습니다.
메모리 계산 방법
상단에 표시되는 숫자는 Android 시스템에 따라 앱에서 커밋한 모든 비공개 메모리 페이지를 기반으로 합니다. 시스템이나 다른 앱과 공유되는 페이지는 포함되지 않습니다. 메모리 카운트의 카테고리는 다음과 같습니다.
- Java: 자바 또는 Kotlin 코드에서 할당된 객체의 메모리.
Native: C 또는 C++ 코드에서 할당된 객체의 메모리
앱에서 C++를 사용하지 않더라도, Android 프레임워크에서 이미지 애셋 및 기타 그래픽을 처리하는 경우와 같이 개발자 대신 다양한 작업을 처리하기 위해 네이티브 메모리를 사용하므로 코드가 Java 또는 Kotlin으로 작성된 경우에도 일부 사용된 네이티브 메모리가 여기에 표시될 수 있습니다.
그래픽: GL 표면, GL 텍스처 등 픽셀을 화면에 표시하기 위해 그래픽 버퍼 대기열에 사용되는 메모리입니다. 이 메모리는 전용 GPU 메모리가 아니라 CPU와 공유됩니다.
스택: 앱의 네이티브 및 Java 스택에서 사용하는 메모리입니다. 일반적으로 앱에서 실행 중인 스레드 수와 관련이 있습니다.
코드: 앱에서 DEX 바이트 코드, 최적화되거나 컴파일된 DEX 코드, .
so
라이브러리, 글꼴Others: 앱에서 사용하는 메모리 중 시스템에서 분류하는 방법을 알지 못하는 메모리.
Allocated: 앱에서 할당한 Java/Kotlin 객체 수입니다. C 또는 C++에서 할당된 객체는 계산되지 않습니다.
할당 기록 검사
할당 기록을 검사하려면 다음 단계를 따르세요.
- 표 탭에서 클래스 목록을 둘러보고 할당 또는 총 개수 값이 비정상적으로 크고 (최적화 대상에 따라 다름) 누출될 가능성이 있는 객체를 찾습니다.
- Instance View 창에서 인스턴스를 클릭합니다. 인스턴스에 적용되는 항목에 따라 필드 또는 할당 호출 스택 탭이 열립니다. 필드 또는 할당 호출 스택 탭의 정보를 사용하여 인스턴스가 정말로 필요한지 아니면 불필요한 중복인지 확인합니다.
목록 항목을 마우스 오른쪽 버튼으로 클릭하여 관련 소스 코드로 이동합니다.
글로벌 JNI 참조 보기
Java Native Interface (JNI)는 Java 코드와 네이티브 코드가 서로를 호출할 수 있도록 지원하는 프레임워크입니다. JNI 참조는 네이티브 코드에 의해 수동으로 관리되므로 다음과 같은 문제가 발생할 수 있습니다.
- 네이티브 코드에서 사용하는 Java 객체가 너무 오랫동안 연결된 상태로 유지됩니다.
- JNI 참조가 먼저 명시적으로 삭제되지 않고 취소되면 Java 힙의 일부 객체에 도달하지 못할 수도 있습니다.
- 글로벌 JNI 참조 한도가 소진되었습니다.
이러한 문제를 해결하려면 프로파일러에서 JNI 힙 보기를 선택하여 모든 전역 JNI 참조를 둘러보고 Java 유형 및 네이티브 호출 스택을 기준으로 필터링하세요. 필드 탭에서 인스턴스 필드를 마우스 오른쪽 버튼으로 클릭하고 인스턴스로 이동을 선택하여 관련 할당 호출 스택을 확인합니다.
Allocation Call Stack 탭에는 코드에서 JNI 참조가 할당되고 해제된 위치가 표시됩니다.
JNI에 관한 자세한 내용은 JNI 도움말을 참고하세요.