안드로이드 런타임은 JVM 기반의 Dalvik을 사용하고 있고, 4.4 Kitkat부터는 ART가 추가 되었다. ART에 대해서는 다음 기획에 정리해보자. 

JVM 기반이라고 하여도, memory leak은 항상 발생할 수 있다. 앱에 memory leak이 사용자 터치마다 발생하면 명확히 앱은 OutOfMemory exception을 발생시키고, 앱을 종료시킬 것이다. 

그러나, 미묘하게 OutOfMemory를 발생시키지 않더라도, 계속적인 Garbage collection을 빈번히 발생시켜, 앱과 전체 시스템의 성능에 문제를 일으킬 수 있다. 

 

주요한 메모리 정보를 얻을 수 있는 도구로는 DDMS를 이용하면 유용한 정보들을 얻을 수 있고, 아래에 설명하고자 하는 내용도 DDMS를 이용한 방법이다. 

Android SDK엔, 메모리 사용을 프로파일링 할 수 있는 툴로, DDMS의 Allocation Tracker와 heap dumps를 제공한다. 

Allocation Tracker는 주어진 기간 동안 allocation의 어떤 종류들이 발생하는 지를 알기 위해서 유용하다. 그러나, app의 heap의 전반적인 상태에 대한 정보를 얻을 수는 없다. 




Heap dump는 application의 heap의 snapshot이다. 그리고, Java의 HPROF와 유사한 (동일하지는 않는) 형태의 바이너리 포맷을 저장된다. 

실행 중인 android app heap dump HPROF 파일을 만들 수 있는 방법으론,

1. DDMS에서 Dump HPROF file button을 눌러주기. 

2. 프로그램에서 heap dump를 생성하기 위해서는, android.os.Debug.dumpHprofData() 함수를 사용하면 된다. 

Heap dump를 분석을 위해서는 jhat이나 Eclipse Memory Analyzer (MAT)를 사용은 가능하나, Dalvik 포맷을 J2SE포맷으로 변환해주어야 한다. 이는 

> hprof-conv dump.hprof converted-dump.hprof
를 통해서 할 수 있다. Eclipse MAT가 설치되어 있는 경우에, DDMS에서 dump HPROF를 하면 자동으로 Eclipse MAT에서 사용가능한 hprof형식으로 변환해준다. 

 

MAT은 매우 강력한 툴로, 설명을 할려면, 그 자세한 내용은 생략하고, 

leak을 검출하기 위해서 MAT의 histogram view를 이용해보자. 

각 class의 리스트는 instance의 수, shallow heap(모든 인스턴스들이 사용하는 메모리의 총량), retained heap(그들이 참조를 가지고 다른 객체들을 포함하여, 모든 객체들에 의해서 현재 보유되고(kept alive) 있는 메모리의 총량)으로 정렬 할 수 있다. 

shallow heap으로 정렬하면, byte[]의 인스턴스를 들을 top으로 볼 수 있는데, android 3.0이상에선 Bitmap object들의 pixel 데이터가 byte 배열로 저장된다. 이전 버전에선 dalvik heap에 저장되지 않는다.)

byte[] class를 선택하고, List Objects > with incomming references를 선택. heap에 있는 모든 바이트 배열의 리스트를 보여준다. 그리고 이것은 Shallow Heap 사용에 기본하여 정렬할 수 있다.

그리고 아래 그림처럼 어디에 어떻게 메모리를 사용하는 지 볼 수가 있다.  

MAT은 leak여부를 판단할 수는 없다. 필요한 객체인지 아닌지는 사용자가 파악하여야 한다. 


MAT을 이용하여 heap dump파일들 비교하기. 

메모리 leak을 판단하기 위해선, 다른 시점에 저장한 덤프 파일을 비교하는 것이 효과적이다.  다른 시점의 HRPOF파일을 생성(hprof-conv를 이용하여 변환)이 필요하다. 

그리고, 비교를 위해선,

  1. 첫번째 HPROF파일을 열고
  2. histogram view를 연다. 
  3. 또 다른 HPROF 파일을 연다. 
  4. histogram view의 네비게이션 바에서 Compare to another heap dump를 눌러서 읽혀 있는 다른 hprof파일과 비교한다. 

시간에 따른 메모리 비교량을 확인할 수 있다. 




Posted by 눈사람
,