SlideShare a Scribd company logo
부채	
  갚기!!	
  
	
  	
  	
  	
  	
  	
  	
  성능	
  최적화	
  :	
  프로파일러	
  사용기	
  
1
Day	
  6.	
  부채	
  갚기!!	
  
	
  	
  	
  	
  	
  	
  	
  성능	
  최적화	
  :	
  프로파일러	
  사용기	
  
2
언제 어디서나 장애물은 있기 마련!
학습	
  목표	
  
• 프로파일러를	
  통해	
  	
  성능에	
  영향을	
  	
  주는	
  장애물을	
  	
  	
  찾아내고,	
  	
  
제거하자.	
  	
  	
  	
  	
  	
  	
  	
  	
  
• BItmap	
  	
  	
  이미지	
  	
  	
  핸들링시	
  	
  주의	
  	
  할점을	
  알수	
  있다.	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
• AndroId	
  Garbage	
  CollectIon	
  의	
  	
  내부	
  동작	
  원리를	
  이해	
  할	
  수	
  
있다.	
  	
  	
  
• 다양한	
  Reference를	
  이해하고,	
  적절히	
  사용할수	
  있다.	
  	
  	
  	
  	
  	
  	
  
4
생각해보기
-­‐ 장애물에는 어떤 것들이 있을까?	
  
1) Out	
  of	
  memory	
  
2) Network	
  
3) Low	
  Battery	
  
4) 100%	
  CPU	
  Usage
생각해보기
-­‐ 장애물에는 어떤 것들이 있을까?	
  
1) Out	
  of	
  memory	
  
2) Network	
  
3) Low	
  Battery	
  
4) 100%	
  CPU	
  Usage
이번
 시간에는
 아래의
 두가지를
 학습
 
1. CPU상태
 확인
 
2. 메모리상태
 확인
1. CPU상태 확인하기

:Traceview	
  따라하기,	
  함수/ 클래스별 CPU 실행 시간 확인

:녹음기 사용하는 것과 비슷(녹음버튼 à 녹음 à 녹음종료버튼 à 녹음확
인)	
  
STEP1.	
  
프로파일 메소드 실행
STEP2.	
  
어플리케이션 동작
STEP3.	
  
프로파일 메소드 종료	
  
 분석
STEP1.	
  프로파일 메소드 실행	
  
1)DDMS 선택
STEP1.	
  프로파일 메소드 실행	
  
2) 기기 선택
STEP1.	
  프로파일 메소드 실행	
  
3)Start	
  Method	
  Profiling 클릭	
  
: 지금부터 어플리케이션의 모든 동작은 프로파일링
클릭을 하고나면 위와 같은 아이콘으로 변경(동작상태)
STEP2.	
  어플리케이션 동작
ex	
  
:	
  사진업로드 하는 과정에서 함수/클래스별 CPU사용 시간을 확인	
  
-­‐프로파일 메소드를 실행한 상태에서 확인하고자 하는 동작을 직접 실행
STEP3.	
  프로파일 메소드 종료 분석
Stop	
  Method	
  Profiling	
  를 클릭하면 아래와 같은 분석결과가 팝업
STEP3.	
  프로파일 메소드 종료 분석
1. A)는 CPU를 사용한 메소드/클래스를 시간대 별로 보여줍니다.	
  
2. B)는 전체 CPU사용량을 100%라고 했을 때 각 메소드/클래스의 사용량을

보여줍니다.	
  
A)
B)
STEP3.	
  프로파일 메소드 종료 분석	
  -­‐	
  A	
  
1. 시간의 범위를 지정하면 보다 자세히 시간대별 사용량을 볼 수 있습니다.	
  
2. 각 색이 뜻하는 것은 사용량을 나타내는 표(B)의 색과 일치합니다.

ex)	
  Dalvik/system/VMDbbug.StargGC	
  ()
STEP3.	
  프로파일 메소드 종료 분석 -­‐	
  B	
  
1. 차지하는 비중이 높은 순서대로 정렬합니다.	
  
2. 항목을 클릭하면 Parent와 children으로 구성되어 있습니다.

ex)	
  1(android/os/Handler.dipatchMessage)을 기준으로 보면 

-­‐	
  Parents(0)는 1을 호출합니다.

-­‐	
  Children(2,	
  39,	
  120,	
  1276,	
  2521)은 1이 호출한 것입니다.
1. 부모가 차지하는 비중에서 자신이 부모에게 차지하는 비중을 곱한 것입니다.	
  	
  
2. 아래의 예시를 통해 보면 2(android/os/Handler/handleCallback)은	
  
부모의 사용량 75% 중에서 86%를 차지했기 때문에 75	
  X	
  0.86	
  =	
  65.6%가 됩니다.	
  
왜 Percentage의 합이 100%가 아닌지 의문이 생길 수 있습니다.	
  
전체에서 2가 차지하는 비중
부모에서 2가 차지하는 비중
전체에서 부모가 차지하는 비중
100%
60%
30%
10%
부모자식관계
60%
30%
10%
36%
24%
15%
15%
60%
40%
50%
50%
100%	
  x	
  60%	
  x	
  60%	
  =	
  36%100%	
  x	
  60%	
  =	
  60
100%	
  x	
  60%	
  x	
  40%	
  =	
  24%100%	
  x	
  30%	
  =	
  30
100%	
  x	
  30%	
  x	
  50%	
  =	
  15%
100%	
  x	
  30%	
  x	
  50%	
  =	
  15%
Tree로 나타내면 다음과 같습니다.
따라해보기
1) 본인의 어플리케이션의 시나리오를 만든다.	
  
2) 각 시나리오별 Method	
  Profiling을 해본다.	
  
3) 시나리오별 CPU를 많이 사용하는 메소드/클래스를 확인한다.
2. 메모리상태 확인하기
STEP1.	
  
	
  Monitor	
  memory	
  
실행하기
STEP2.	
  
Heap	
  Dump
STEP3.	
  
Allocation Tracker
:Android	
  Studio을	
  통해	
  heap의 정보를 얻어서 메모리 상태를 확인
[참고링크]	
  	
  
http://developer.android.com/tools/studio/index.html#git-­‐samples
STEP4.	
  
Eclipse MAT
  그전에 Android	
  Memory와 Garbage	
  collection	
  	
  
	
   (이하 GC)에 대해서 알아보겠습니다.
java.lang.OutOfMemoryError:	
  bitmap	
  size	
  exceeds	
  VM	
  budget
흔히 발생하는 상황
구글에서 	
  
메모리 누수 현상이 자주 발생해서 메모리 관리 체계를 변경합니다.
Honeycomb이전 Honeycomb이후
이미지 파일
이전에는 	
  Native영역에서 이미지 파일을 관리했다면,	
  	
  이후에는 Dalvik내부에서 관리를 하는
구조로 변경되었습니다.	
  
Q	
  : 이미지파일의 저장위치가 핵심인가요?	
  
A	
  :	
  이미지가 메모리 누수의 50~70%를 차지하기 때문에
App
 
 
Memory
App
 
Memory
App
 
Memory
App
 
Memory
App
 
Memory
Dalvik
 is
 Isolation
 model
DALVIK
‘이미지 저장위치’의 변경만 확인하시고 나머지는 	
  
이어서 자세히 설명하겠습니다.	
  
Honey	
  Comb 이전 Honey	
  Comb 이후
이미지 저장 위치 Dalvik외부 native	
  Heap Dalvik 내부
GC 동작 전체 App이 멈춤 부분적으로 진행(partially)
Bitmap의 GC GC의 대상이 아님 GC의 대상
다른 App의 영향 메모리 누수가 발생하면 다른 App
도 함께 죽음
다른 앱에 영향이 없음
1) Garbage	
  Collection(GC)는 사용하지 않는 메모리를 정리하는 것입니다.	
  	
  
2) Mark	
  	
  Sweep

-­‐	
  Mark	
  :	
  GC	
  Roots를 통해서 연결된 객체를 표시(Mark)합니다.	
  	
  

-­‐	
  Sweep	
  :	
  Mark되지 않은 객체는 사용하지 않는 객체로 간주하여 삭제(Sweep)합니다.
지금부터 GC에 대해서 알아보겠습니다.
1. GC_CONCURRENT	
  :	
  heap영역이 계속 커질 때 새롭게 heap을 확대하지 않고,	
  

메모리 회수로 가능한 경우

2. GC_EXPLICIT	
  :	
  System에서 주기적으로 GC를 호출하는 경우

	
  	
  
3. GC_EXTERNAL_MALLOC	
  :	
  BITMAP처럼 외부의 메모리를 할당 받은 경우, 하지만 honey-­‐comb
이후 버전부터는 bitmap을 dalvik	
  heap(internal	
  heap)에 할당하기 때문에 이전 버전에만 해
당 

4. GC_FOR_MALLOC	
  :	
  heap영역이 가득 찬 경우 전체 어플리케이션을 멈추고 GC를 진행

5. GC_HPROF_DUMP_HEAP	
  :	
  메모리 분석을 위해 HPROF	
  file을 만든 경우
아래와 같은 이유로 GC가 일어납니다.	
  
Honey	
  Comb 이전 Honey	
  Comb 이후
저장 위치 Dalvik외부 native	
  Heap Dalvik 내부
GC 동작 전체 App이 멈춤 부분적으로 진행(partially)
Bitmap의 GC GC의 대상이 아님 GC의 대상
다른 App의 영향 메모리 누수가 발생하면 다른 App
도 함께 죽음
다른 앱에 영향이 없음
1) GC동작 방식

-­‐	
  HoneyComb 이전에는 전체 App이 멈추는 Serial	
  MarkSweep(Stop	
  the	
  world)방식이였습니다.

-­‐ 이후에는	
  부분적으로 진행하는 Concurrent	
  MarkSweep으로 변경되었습니다.	
  	
  

2) Concurrent	
  MarkSweep 장점 

-­‐ 반응성/속도

	
   	
   부분적으로 동작하기 때문에 앱이 멈추지 않습니다.

	
   	
   Serial	
  MarkSweep	
  :	
  100ms,	
  Concurrent	
  MarkSweep	
  5ms

3) Concurrent	
  MarkSweep 단점

-­‐ 이전보다 메모리와 CPU를 더 많이 사용하게 되었습니다.
앞에서 본 표입니다.	
  
이번 슬라이드에서는 ‘GC동작 부분’만 확인해보겠습니다.
(다른작업도 쓰레드로 진행가능)
[출처]	
  Hello	
  world	
  :	
  Android	
  앱 메모리 최적화편
Serial	
  MarkSweep과 Concurrent	
  MarkSweep 동작 비교
직접 메모리를 관리하고 싶다면,
Java에서는 C,	
  C++에서 사용하는 ‘free’,	
  ‘delete’가 없기 때문에	
  주기적으로 혹은 특정 조건일 때 GC
를 하게 됩니다. 이로인해 프로그래머는 메모리 관리에 대해서 고민을 적게 할 수 있습니다.	
  
하지만 임베디드 환경(모바일 포함)에서는 이 메모리 하나 하나가 매우 소중합니다.	
  
예를들어 1회성으로 할당한 공간을	
  GC과정에서 ‘사용하는 메모리’라고 판단하여 공간을 계속 잡게
될 경우 불필요한 공간낭비로 메무리 누수의 위험이 생길 수 있습니다.	
  
기본적으로 할당하는 방식은 Strong	
  Reference입니다.
Strong	
  
	
   -­‐	
  기본적으로 할당하는 방식을 Strong	
  Reference	
  라고 부릅니다.

	
   	
   	
  mLauncher	
  =	
  new	
  Launcher(launcher);	
  
	
   -­‐	
  GC과정에서 연결된 객체들을 Mark하고 Mark되지 않은 객체들을 Sweep합니다.	
  	
  
	
   즉 메모리 관리에 프로그래머가 신경쓰지 않습니다.	
  
	
  
Strong	
  이외에 3가지가 더 있습니다.
1.	
  종류 

	
   Soft	
  reference,	
  Weak	
  reference,	
  Phantom	
  reference

	
   	
   Private	
  WeakReferenceLauncher	
  mLauncher;	
  
	
   	
   mLauncher	
  =	
  new	
  WeakReferenceLauncher(launcher);	
  
2. 원리	
  
	
   -­‐	
  GC동작에서 Strong이 아닌 경우 Mark하지 않고 Reference	
  Queue라는 공간에 객체를 넣고,	
  

	
   	
  	
  	
  Sweep하는 과정에서 제거 Queue에 있는 객체들을 제거 합니다.	
  	
  
3.	
  차이점	
  
	
   이름에서 느낄 수 있듯이 객체간의 연결정도를 나타냅니다. 그리고 이 연결정도가 강할수록 제거가 	
  
	
   되지 않습니다. 객체간의 연결정도를 수식으로 나타내면 Strong	
  	
  Soft	
  	
  Weak	
  	
  Phantom	
  순서입니다.
더 자세히 보겠습니다.	
  
1. Soft	
  reference	
  
Mark가 되기도 하고 Reference	
  Queue에 담기기도 합니다.	
  
Soft	
  reference로	
  참조된 객체는 메모리가 절대적으로 부족한 상황이 되기전에는 참조가 유지됩니다.

각 앱마다 할당된 메모리가 절대적을 부족할 때 그 Reference가 Soft이면 제거, 여유롭다면 Strong과 같이 제거
하지 않습니다.	
  
2.	
  Weak	
  reference	
  
Referene	
  Queue에 담깁니다.	
  
Weak	
  reference로	
  참조된 객체는 Soft	
  Reference보다 더 약한 연결고리를 가집니다.	
  메모리의 상태와 관계없이
GC가 동작되는 순간	
  Marked	
  Object라도 회수됩니다.	
  
Strong Soft
Weak
Phantom
Mark
Reference	
  Queue
3.	
  Phantom	
  reference	
  
-­‐	
  GC가 아닌 코드 내에서 바로 Reference	
  Queue에 넣습니다.	
   그렇기 때문에 반드시 Reference	
  Queue와 함께
사용해야 합니다.	
  
-­‐	
  Weak	
  Reference와 유사하며,	
  finalize 시점에서 메모리를 바로 정리하지 않고 Reference	
  Queue에 참조를 등
록하여 코드에 접근 할 수 있도록 합니다. 객체의 자원 정리를 구현하기 위해 사용할 수 있습니다.	
  	
  
예제 코드 	
  
ReferenceQueue	
  q	
  =	
  new	
  ReferenceQueue();	
  
PhantomReference	
  pr	
  =	
  new	
  PhantomReference(object,	
  referenceQueue);	
  
//	
  Later	
  on	
  another	
  point	
  
Reference	
  r	
  =	
  q.remove();	
  
//	
  Now,	
  clear	
  up	
  any	
  thing	
  you	
  want
Strong Soft
Weak
Phantom
Mark Reference	
  Queue


-­‐	
  Strong	
  :	
  연결된 객체들을 체크 합니다.

-­‐	
  Soft	
  :	
  메모리 상태에 따라 Mark하거나,	
  	
  Reference	
  Queue에 

	
   넣습니다.

-­‐	
  Weak	
  :	
  Reference	
  Queue에 넣습니다.

-­‐	
  Phantom	
  : 코드상에서 바로 Reference	
  Queue에 넣습니다.
Reference에 따른 Mark과정 차이
GC 전 GC 후GC 중
Strong	
  Reference 동작 방식
기본 컨셉	
  
-­‐ Mark	
  	
  Sweep	
  :	
  GC-­‐Roots로부터 연결된 인스턴스들을 마크합니다. 그리고 마크되지 않은 객체들을 제거
(Sweep)합니다.	
  
-­‐ Reachability	
  :	
  Roots로 부터 도달(참조) 가능한 객체(rechable)와 도달 할 수 없는 객체(un	
  reachable)로 나눕
니다.	
  	
  	
  
-­‐ 프로그래머가 GC에 관여하지 않고 Mark되는 방식에 따라 Mark하고 Mark하지 않은 것들을 Sweep합니다.
마크되는 과정은 아래와 같습니다.
Mark	
  Bit
1
1
1
GC	
  Roots
A
B
C
D
E
F
G
H
A
B
C D
G F
H
E
1
D1
Mark를 모두 마친 후 제거(Sweep)를 하게 됩니다.	
  
UnmarkedSweep	
  :	
  Mark	
  되지 않은 메모리를 회수합니다.
1
Mark-­‐Bit
1 1 제거 대상
GC 전 GC 후GC 중
Soft,	
  Weak,	
  Phantom 동작 방식
기본 컨셉	
  
-­‐ Strong과 마찬가지로 Mark	
  	
  Sweep 방식으로 이루어집니다.	
  
-­‐ 다른 부분은 Mark되지 않는다는 것입니다.

	
   Soft	
  	
  :	
  메모리 상태에 따라 Mark하거나 Reference	
  Queue에 넣습니다.

	
   Weak	
  :	
  Mark하지 않고	
  Reference	
  Queue에 넣습니다.

	
   Phantom	
  :	
  코드상에서 바로 Reference	
  Queue에 넣습니다.	
  
-­‐ Sweep

	
   Reference	
  Queue에 넣어 두었던 객체들을 제거 합니다.
Mark	
  Bit
1
1
1
GC	
  Roots
A
B
C
D
E
F
G
H
A
B
C D
G F
H
E
1
이전에 봤던 마크되는 과정입니다.	
  
여기서 Mark된 B객체가 Soft 혹은 Weak	
  Reference라면?
Mark	
  Bit
1
1
1
GC	
  Roots
A
B
C
D
E
F
G
H
A
B
C D
G F
H
E
1
이전에 봤던 마크되는 과정입니다.	
  
여기서 Mark된 B객체가 Soft 혹은 Weak	
  Reference라면?
Reference	
  Queue
B
Reference	
  Queue에 넣은 뒤 제거(Sweep)를 하게 됩니다.	
  
heapSweepSystemWeak	
  :	
  Mark하는 과정에서 reference	
  queue에 넣어두었던 Soft,	
  Weak,	
  Phantom	
  
Object의 메모리를 회수합니다.	
  
Reference	
  Queue
a b
Strong Soft
Weak
Phantom
Mark Reference	
  Queue


-­‐	
  Strong	
  :	
  연결된 객체들을 체크 합니다.

-­‐	
  Soft	
  :	
  메모리 상태에 따라 Mark하거나,	
  	
  Reference	
  Queue에 

	
   넣습니다.

-­‐	
  Weak	
  :	
  Reference	
  Queue에 넣습니다.

-­‐	
  Phantom	
  : 코드상에서 바로 Reference	
  Queue에 넣습니다.
GC를 다시 한번 정리하면	
  Mark가 먼저 동작합니다.
Mark 후에는 Sweep이 이루어집니다.	
  
3가지 동작이 이루어집니다.
1) heapSweepSystemWeak	
  :	
  Mark하는 과정에서 reference	
  queue에 넣어두었던 Soft,	
  Weak,	
  
Phantom	
  Object의 메모리를 회수합니다.	
  
2) BitmapSweep	
  : 이미지의 메모리를 회수 합니다.	
  
3) UnmarkedSweep	
  :	
  Mark	
  되지 않은 메모리를 회수합니다.
Reference	
  Queue
a b
1
Mark-­‐Bit
1 1 제거 대상
Mark 후에는 Sweep이 이루어집니다.	
  
이미지 객체 회수에 대해서 더 알아보겠습니다.	
  
-­‐ Bitmap은 GC에서 매우 중요한 부분입니다.	
  
-­‐ 메모리 누수의 원인은 대부분 이미지와 관련되어 있습니다.	
  
-­‐ 그래서 안드로이드에서는 Honey	
  Comb이전과 이후로 Bitmap을 다르게 관리하고 있습니다.
Honey	
  Comb 이전 Honey	
  Comb 이후
저장 위치 Dalvik외부 native	
  Heap Dalvik 내부
GC 동작 전체 App이 멈춤 부분적으로 진행(partially)
Bitmap의 GC GC의 대상이 아님 GC의 대상
다른 App의 영향 메모리 누수가 발생하면 다른
App도 함께 죽음
다른 앱에 영향이 없음
HoneyComb 이전에는 왜 그랬을까요?
-­‐ 왜 저장 위치를 밖에 두었을까요?

Honeycomb이전에는 그래픽 라이브러리를 c++의 skia 라이브러리를 사용했습니다. 그래서 비트맵도
native메모리에 로딩될 수 밖에 없었고, 이를 많이 잡아먹으면 다른 앱에서 사용할 수 없었기 때문에 한계
를 정해 두었습니다.



HoneyComb 이후 이점은 무엇일까요?
	
  	
  
-­‐ 저장 위치를 dalvik	
  heap으로 bitmap을 옮겼고,	
  GC를 할때 bitmap도 함께 관리를 할 수 있게 됩니다.

-­‐ 이전에는 App의 GC가 이루어진다고 해도 bitmap은	
  native영역에 존재하기 때문에 GC의 대상이 되지 않
았습니다.	
  bitmap이 native영역을 차지하게 되면 다른 앱을 사용하는데 제약을 받게 됩니다. 이를 해결하
기 위해서는 수동으로 Finalize()와 Recycle()을 통해 직접 native영역에서 메모리를 회수해야 했습니다.



  	
   이제 메모리를 	
  
	
   	
   어떻게 확인하는지 알아봅시다.
2. 메모리상태 확인하기
STEP1.	
  
	
  Monitor	
  memory	
  
실행하기
STEP2.	
  
Heap	
  Dump
STEP3.	
  
Allocation Tracker
:Android	
  Studio을	
  통해	
  heap의 정보를 얻어서 메모리 상태를 확인
[참고링크]	
  	
  
http://developer.android.com/tools/studio/index.html#git-­‐samples
STEP4.	
  
Eclipse MAT
STEP1.	
  Monitor Memory 실행하기
Memory 탭을 선택합니다.
어플리케이션	
  run	
  상태에서	
  Android	
  Studio	
  하단의	
  Android	
  탭을	
  선택합니다.
STEP1.	
  Monitor Memory 실행하기
or build.gradle의 buildTypes에 debuggable true를 추가합니다.
Tools	
  -­‐	
  Android	
  -­‐	
  Enable	
  ADB	
  Integration을	
  활성화시킵니다.
-­‐	
  실행중인	
  어플리케이션을	
  선택할	
  수	
  없을	
  때는?
http://stackoverflow.com/questions/26593927/android-­‐studio-­‐no-­‐debuggable-­‐applications
STEP1.	
  Monitor Memory 실행하기
실행	
  중인	
  어플리케이션에	
  할당된	
  메모리	
  크기를	
  확인할	
  수	
  있습니다.
STEP2.	
  Dump	
  HPROF	
  file	
  
Monitor	
  Memory에서	
  	
  Dump	
  Java	
  Heap	
  icon	
  을	
  클릭해서	
  
현시점의	
  Heap의	
  스냅샷을	
  생성합니다.
STEP2.	
  Heap	
  Dump
	
  스냅샷	
  파일은	
  Snapshot-­‐yyyy.mm.dd-­‐hh.mm.ss.hprof	
  이름으로	
  	
  
Captures	
  탭에	
  저장되어	
  있습니다.
 스냅샷	
  파일을	
  더블클릭하면	
  아래와	
  같이	
  메모리	
  상태를	
  확인할	
  수	
  있습니다.
STEP2.	
  Heap	
  Dump
클래스,	
  인스턴스,	
  참조트리를	
  확인할	
  수	
  있습니다.	
  	
  
메모리	
  사용량을	
  확인하고	
  메모리	
  릭	
  발생지점을	
  찾는	
  데	
  유용합니다.
STEP2.	
  Heap	
  Dump
분석 전에 몇가지 개념에 대해서 알아보겠습니다.	
  
AC
1. Dominator	
  Tree	
  

-­‐	
  아래 그림은 Garbage	
  Collection을 할때 자주 봤던 트리입니다.

-­‐ 이 트리가	
  Dominator	
  Tree입니다.

-­‐	
  Dominator	
  Tree란 객체간 연결을 나타낸 것으로 객체 간의 참조를 보여줍니다.













2. Shallow	
  Heap

-­‐	
  Object	
  하나가 가지는 byte를 나타냅니다.

3. Retain	
  Heap

-­‐	
  	
  GC를 통해 한 Object를 제거 될때 제거되는 총 메모리의 양입니다.

-­‐	
  Object가 참조하는 모든 Object의 총 합으로 실질적인 메모리 사용량입니다.	
   

-­‐ 예를 들어 A를 제거할 경우 C까지 포함한 메모리의 양을 Retain	
  Heap이라고 합니다.

Reference Tree 탭에서는 연관된 객체들의
Shallow	
  Heap, Retained	
  Heap을 보여줍니다.
STEP2.	
  Heap	
  Dump
Instance	
  탭에서는	
  	
  
Dominator Tree, 객체 정보에 대해서	
  확인 할 수 있습니다.	
  
STEP2.	
  Heap	
  Dump
A CB D
E
왼쪽과 같은 Dominator Tree를
아래 표로 정리한 입니다.
-­‐ A	
  :	
  0x42efcad0	
  
-­‐ B	
  :	
  0x42d4f4e8	
  
-­‐ C	
  :	
  0x42d4f528	
  
-­‐ D	
  :	
  0x4248c3c8	
  
-­‐ E	
  :	
  0x42d4f510	
  
-­‐ F	
  :	
  0x42d4d108	
  
-­‐ G	
  :	
  0x42d4f3d8
F
G
STEP2.	
  Heap	
  Dump
스냅샷파일의	
  우클릭한후	
  Export	
  to	
  standard.hprof	
  를	
  클릭하면,	
  
표준	
  HPORF	
  파일을	
  생성할	
  수	
  있습니다.	
  
생성된	
  표준	
  파일과	
  Eclipse	
  MAT를	
  통해서도	
  메모리	
  사용을	
  분석할	
  수	
  있습니다.
STEP2.	
  Heap	
  Dump
[참고영상]	
  	
  
Google	
  I/O	
  2011:	
  Memory	
  management	
  for	
  Android	
  Apps	
  
	
   https://www.youtube.com/watch?v=_CruQY55HOk
STEP3.	
  Allocation Tracker
	
  	
  	
  	
  	
  Allocation	
  Tracker	
  에 대해서 보겠습니다.
-­‐	
  	
  특정 액션을 취했을 때의 메모리 할당의 변화를 관찰하기 위해서 사용합니다.
Start	
  Allocation	
  Tracking을	
  눌러	
  메모
리	
  할당	
  모니터링을	
  시작합니다.
STEP3.	
  Allocation Tracker
-­‐	
  	
  특정 액션을 취했을 때의 메모리 할당의 변화를 관찰하기 위해서 사용합니다.
어플리케이션	
  내에서	
  특정	
  액션을	
  수행하고,	
  
모니터링	
  시작할	
  때	
  눌렀던	
  아이콘과	
  동일한	
  아이콘을	
  눌러모니터링을	
  중지합니다.
STEP3.	
  Allocation Tracker
Captures 탭의 Allocation Tracking 폴더에 파일이 생성됩니다.
더블클릭하면 메모리 할당 결과를 확인할 수 있습니다.
STEP3.	
  Allocation Tracker
STEP3.	
  Allocation Tracker
메서드, 클래스 별로 특정한 액션을 취한 후 할당된 메모리량을 확인할 수 있습니다.
STEP4.	
  Eclipse	
  MAT
1)
2)
다음 슬라이드에 확대된 스크린샷이 있습니다	
  :D
Eclipse	
  를	
  실행하여	
  Plug-­‐in	
  을	
  설치합시다.
1)
STEP4.	
  Eclipse	
  MAT
2)
STEP4.	
  Eclipse	
  MAT
3)
STEP4.	
  Eclipse	
  MAT
Android	
  Studio에서	
  스냅샷을	
  생성한	
  후	
  표준	
  hprof	
  파일을	
  생성합니다.
4) Eclipse DDMS 에서 표준 hprof 파일을 엽니다.
Leak	
  Suspects	
  :	
  메모리 누수가 의심되는 곳을 알려줍니다.	
  	
  
간단한 설명과 함께 Details를 통해 자세한 정보를 제공합니다.	
  
STEP4.	
  Eclipse	
  MAT
Details를 통해 자세한 정보를 보면, 그림과 같이 연관된 객체들의
Shallow	
  Heap과 Retained	
  Heap을 보여줍니다.
STEP4.	
  Eclipse	
  MAT
-­‐ 텝 상단에 보면 트리모양의 아이콘이 있습니다.	
  
-­‐ 그 아이콘을 누르면 Dominator	
  Tree를 확인할 수 있습니다.	
  
STEP4.	
  Eclipse	
  MAT
  어플리케이션에서 생성된 객체들의 정보에 대해서 	
  
	
   확인 할 수 있습니다.	
  
STEP4.	
  Eclipse	
  MAT
-­‐ 두 개 중 아무 덤프나 클릭 후 아래에 표시된 아이콘을 클릭합니다.
A경우에 대한 덤프 B경우에 대한 덤프
STEP4.	
  Eclipse	
  MAT
-­‐ 생성된 Object들의 크기정보를 표로 보여줍니다.	
  
-­‐ 여기서 상단메뉴 우편에 아이콘을 클릭하면 비교할 대상을 지정할 수 있습니다.
STEP4.	
  Eclipse	
  MAT
-­‐ 비교할 대상을 지정합니다.	
  
STEP4.	
  Eclipse	
  MAT
-­‐ A	
  :	
  Object 각각에 대한 수와 Shallow	
  heap의 변화를 보여줍니다.	
  	
  
-­‐ B:	
  전체 Object수 변화와 Shallow	
  heap의 변화를 보여줍니다.	
  
A
B
STEP4.	
  Eclipse	
  MAT
지금부터 내용은 ‘SUPER’ 중요합니다!	
  
주인공은 마지막에 등장하죠!
안드로이드 앱에서 Memory의 핵심 bitmap!	
  
평균 50%에서 최대 70%까지 차지합니다.
상위 모든 항목이 Bitmap과 관련되어 있습니다!!!!!	
  
핵심은 Bitmap!	
  Bitmap만 잡자!
 	
  
1. 이미지 품질 줄이기	
  
2. Bitmap	
  recycle()	
  호출	
  
3. Bitmap을 불러올 때 사이즈 줄이기	
  
4. Cache 사용	
  
5. Reference	
  
6. Async 구현
So	
  what?	
  그래서 어떻게 하라고 ?
1. 이미지 품질줄이기
res폴더에 이미지 파일을 넣으면 자동으로 손실없이 최적화하게 됩니다.	
  24비트 이미지더라도 256색 이상
을 사용하지 않았다면 8비트로 파일변환하게 됩니다. 품질은 똑같지만 메모리는 적게 차지하게 됩니다.	
  
하지만 asset	
  최적화를 하지 않습니다. 그러므로 이미지 품질이 중요하지 않다면 8bit	
  RGB_565옵션을 권
장합니다.(위의 표에서 볼 수 있듯이 1/4수준)	
  
[오해할 수 있는 부분]	
  
위의 표는 res와 asset의 메모리 사용 비교가 아닙니다. 핵심은 res쪽은 안드로이드에서 최적화를 하니 신
경 쓸 필요가 없고 asset 폴더나 스토리지에 있는 파일은 최적화를 안드로이드에서 하지 않으니 프로그래
머가 ‘알아서’ 조절해야 된다는 겁니다. 품질이 중요하다면 위의 옵션이 아닌 고품질을 유지하고,	
  중요하지
않다면 옵션을 설정해서 메모리를 줄이는 것이 좋습니다.
2.	
  	
  Bitmap	
  recycle()	
  호출
HoneyComb이후로 bitmap이 GC의 대상이 되기 때문에(처음 들은 것 같다면 background 참고) 참조만 끊어도 GC
이 되지만,	
  HoneyComb이전 혹은 확실히 하고 싶다면 recycle()을 통해 확실히 하는 것이 좋습니다.
Bitmap을 맴버로 선언한 경우
2.	
  	
  Bitmap	
  recycle()	
  호출
HoneyComb이후로 bitmap이 GC의 대상이 되기 때문에(처음 들은 것 같다면 background 참고) 참조만 끊어도 GC
이 되지만,	
  HoneyComb이전 혹은 확실히 하고 싶다면 recycle()을 통해 확실히 하는 것이 좋습니다.
Bitmap을 맴버로 선언하지 않을 경우
3.	
  	
  Bitmap을 불러올 때 사이즈 줄이기
-­‐ 주의! 불러오고나서가 아니라 부르기 전에 사이즈를 줄여야 합니다.

àBitmapFactroy.createScaledBitmap()으로	
  resize하기전에 resize를 하는 것이 좋습니다.	
  
-­‐ BitmapFactory.Option.InSampleSize를 통해 원하는만큼 줄입니다.
실습 : 이미지를 불러오는 ArticleView.java의 소스코드를 수정할 것입니다
아래의 슬라이드부터는 Eclipse 환경에서 작성을 했습니다.
*수정할 부분
실습
-­‐ options.inSampleSize	
  =	
  4;	
  

읽어올때 사이즈를 줄이는 것입니다.

여기서 숫자의 의미는	
  n개의 픽셀을 한 픽셀로 decode 한다는 뜻입니다. 즉 1/n이 줄어들게 됩니다.

추가로 2의 지수 값을 넣는 것이 decode속도를 가장 높일 수 있는 방법입니다.

-­‐ Bitmap	
  resized	
  =	
  Bitmap.createScaledBitmap(bitmap,	
  1000,	
  1000,	
  true);

options.inSampleSize로 크기도 줄어들지만 size도 줄어듭니다.	
  

그렇기 때문에 사용할 크기에 맞춰서 resize를 해줘야 합니다.	
  (bitmap,	
  width,	
  height,	
  filter)	
  
더 알아보기
결과
테스트 : 두개의 사진을 클릭 	
  
결과 :	
  20%절감 (10mega	
  byte	
  à 8	
  mega	
  byte)
4.	
  	
  Cache	
  사용
-­‐ Bitmap이 필요할 때마다 계속 decode하는 것이 아니라 cashe를 통해 저장하여 재사용하는 방법입니다.	
  
-­‐ 캐시의 용량이 커지면 오히려 그 부분에서 메모리 누수가 생길 수 있기 때문에 잘 활용해야 합니다.	
  
-­‐ 안드로이드에서는 메모리케시 (LruCache)와 디스크케시 (DiskCache)를 제공합니다.
실습 : 케시를 사용할 객체를 만들고, 이미지를 불러오는 

	
   ArticleView.java의 소스코드를 수정할 것입니다.
4.	
  	
  Cache 사용 –	
  Cache객체 생성
-­‐ Cache를 사용하는 방법은 다양하게 있습니다.	
  

그 중에서 싱글톤으로 인스턴스를 생성하여, 그 인스턴스가 케시에 저장하고 불러오도록 해보겠습니다.	
  
-­‐ Flickr에서 이 방법을 사용하고 있습니다
1.	
  ImageLoader	
  객체생성
1. maxMemory	
  :	
  현재 메모리를 가져옵니다.	
  
2. cacheSize	
  :	
  전체 메모리 중 케시로 사용할 메모리를 정합니다.	
  
	
  	
  	
  	
  	
  mMemoryCache.get(key)	
  :	
  케시에서 이미지를 가져옵니다.	
  
	
  	
  	
  	
  mMemoryCache.put(key,	
  value)	
  :	
  케시에 이미지를 저장합니다.
4.	
  	
  Cache 사용 – 이미지 불러오기에서 사용
*수정할 부분

More Related Content

What's hot

Reactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単にReactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単に
Yoshifumi Kawai
 
OpenCVで作るスタンプAR
OpenCVで作るスタンプAROpenCVで作るスタンプAR
OpenCVで作るスタンプAR
Takashi Yoshinaga
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
Takeshi Ogawa
 
Lxc で始めるケチケチ仮想化生活?!
Lxc で始めるケチケチ仮想化生活?!Lxc で始めるケチケチ仮想化生活?!
Lxc で始めるケチケチ仮想化生活?!
Etsuji Nakai
 
C++でテスト駆動開発
C++でテスト駆動開発C++でテスト駆動開発
C++でテスト駆動開発
Akineko Shimizu
 
Kapacitorでネットワークにおける リアルタイムイベント検出
Kapacitorでネットワークにおけるリアルタイムイベント検出Kapacitorでネットワークにおけるリアルタイムイベント検出
Kapacitorでネットワークにおける リアルタイムイベント検出
tetsusat
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patternsnekop
 
C# における Redis 徹底活用
C# における Redis 徹底活用C# における Redis 徹底活用
C# における Redis 徹底活用
Takaaki Suzuki
 
オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務
Yutaka Kachi
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
Kohsuke Yuasa
 
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!デベロッパーネットワーク
 
[IMQA] performance consulting
[IMQA] performance consulting[IMQA] performance consulting
[IMQA] performance consulting
IMQA
 
Basic of virtual memory of Linux
Basic of virtual memory of LinuxBasic of virtual memory of Linux
Basic of virtual memory of Linux
Tetsuyuki Kobayashi
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
Yoshifumi Kawai
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
Hajime Yanagawa
 
いまさら恥ずかしくてAsyncをawaitした
いまさら恥ずかしくてAsyncをawaitしたいまさら恥ずかしくてAsyncをawaitした
いまさら恥ずかしくてAsyncをawaitした
Kouji Matsui
 
バージョン管理システム比較資料
バージョン管理システム比較資料バージョン管理システム比較資料
バージョン管理システム比較資料
suzzsegv
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくい
wata2ki
 
年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会
monobit
 

What's hot (20)

Reactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単にReactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単に
 
OpenCVで作るスタンプAR
OpenCVで作るスタンプAROpenCVで作るスタンプAR
OpenCVで作るスタンプAR
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
Lxc で始めるケチケチ仮想化生活?!
Lxc で始めるケチケチ仮想化生活?!Lxc で始めるケチケチ仮想化生活?!
Lxc で始めるケチケチ仮想化生活?!
 
C++でテスト駆動開発
C++でテスト駆動開発C++でテスト駆動開発
C++でテスト駆動開発
 
Kapacitorでネットワークにおける リアルタイムイベント検出
Kapacitorでネットワークにおけるリアルタイムイベント検出Kapacitorでネットワークにおけるリアルタイムイベント検出
Kapacitorでネットワークにおける リアルタイムイベント検出
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patterns
 
C# における Redis 徹底活用
C# における Redis 徹底活用C# における Redis 徹底活用
C# における Redis 徹底活用
 
オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
 
[IMQA] performance consulting
[IMQA] performance consulting[IMQA] performance consulting
[IMQA] performance consulting
 
Basic of virtual memory of Linux
Basic of virtual memory of LinuxBasic of virtual memory of Linux
Basic of virtual memory of Linux
 
Gplとの付き合い方
Gplとの付き合い方Gplとの付き合い方
Gplとの付き合い方
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
 
いまさら恥ずかしくてAsyncをawaitした
いまさら恥ずかしくてAsyncをawaitしたいまさら恥ずかしくてAsyncをawaitした
いまさら恥ずかしくてAsyncをawaitした
 
バージョン管理システム比較資料
バージョン管理システム比較資料バージョン管理システム比較資料
バージョン管理システム比較資料
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくい
 
年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会
 

Similar to [NEXT] Android Profiler 사용법

[NEXT] Android Profiler
[NEXT] Android Profiler[NEXT] Android Profiler
[NEXT] Android Profiler
YoungSu Son
 
안드로이드 Oreo의 변화와 모바일 앱/플랫폼의 적합한 성능 측정 방법
안드로이드 Oreo의 변화와  모바일 앱/플랫폼의 적합한 성능 측정 방법안드로이드 Oreo의 변화와  모바일 앱/플랫폼의 적합한 성능 측정 방법
안드로이드 Oreo의 변화와 모바일 앱/플랫폼의 적합한 성능 측정 방법
YoungSu Son
 
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
YoungSu Son
 
Android 성능 지표와 Oreo 의 개선사항
Android 성능 지표와  Oreo 의 개선사항 Android 성능 지표와  Oreo 의 개선사항
Android 성능 지표와 Oreo 의 개선사항
YoungSu Son
 
Android와 Flutter 앱 개발의 큰 차이점 5가지
Android와 Flutter 앱 개발의 큰 차이점 5가지Android와 Flutter 앱 개발의 큰 차이점 5가지
Android와 Flutter 앱 개발의 큰 차이점 5가지
Bansook Nam
 
[1A4]자바스크립트 라이브러리 개발 운영 경험기
[1A4]자바스크립트 라이브러리 개발 운영 경험기[1A4]자바스크립트 라이브러리 개발 운영 경험기
[1A4]자바스크립트 라이브러리 개발 운영 경험기
NAVER D2
 
deview2014
deview2014deview2014
deview2014
yongwoo Jeon
 
[박민근] 3 d렌더링 옵티마이징_nv_perfhud
[박민근] 3 d렌더링 옵티마이징_nv_perfhud[박민근] 3 d렌더링 옵티마이징_nv_perfhud
[박민근] 3 d렌더링 옵티마이징_nv_perfhudMinGeun Park
 
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
Jaeseung Ha
 
모니터링 영역의 변천사_클라우드, 디지털 경험까지)
모니터링 영역의 변천사_클라우드, 디지털 경험까지)모니터링 영역의 변천사_클라우드, 디지털 경험까지)
모니터링 영역의 변천사_클라우드, 디지털 경험까지)
IMQA
 
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101) 모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
YoungSu Son
 
기술적 변화를 이끌어가기
기술적 변화를 이끌어가기기술적 변화를 이끌어가기
기술적 변화를 이끌어가기
Jaewoo Ahn
 
Codex project
Codex projectCodex project
Codex project
Lee Jungpyo
 
김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법성훈 김
 
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
Chansuk Yang
 
Java performance and trouble shooting
Java performance and trouble shootingJava performance and trouble shooting
Java performance and trouble shooting
Anna Choi
 
[123] electron 김성훈
[123] electron 김성훈[123] electron 김성훈
[123] electron 김성훈
NAVER D2
 
2일차 20140402
2일차 201404022일차 20140402
2일차 20140402
Jake Yoon
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XpressEngine
 
Opensource APM SCOUTER in practice
Opensource APM SCOUTER in practiceOpensource APM SCOUTER in practice
Opensource APM SCOUTER in practice
GunHee Lee
 

Similar to [NEXT] Android Profiler 사용법 (20)

[NEXT] Android Profiler
[NEXT] Android Profiler[NEXT] Android Profiler
[NEXT] Android Profiler
 
안드로이드 Oreo의 변화와 모바일 앱/플랫폼의 적합한 성능 측정 방법
안드로이드 Oreo의 변화와  모바일 앱/플랫폼의 적합한 성능 측정 방법안드로이드 Oreo의 변화와  모바일 앱/플랫폼의 적합한 성능 측정 방법
안드로이드 Oreo의 변화와 모바일 앱/플랫폼의 적합한 성능 측정 방법
 
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
클라우드 & 모바일 환경에서 알아야 할 성능 품질 이야기
 
Android 성능 지표와 Oreo 의 개선사항
Android 성능 지표와  Oreo 의 개선사항 Android 성능 지표와  Oreo 의 개선사항
Android 성능 지표와 Oreo 의 개선사항
 
Android와 Flutter 앱 개발의 큰 차이점 5가지
Android와 Flutter 앱 개발의 큰 차이점 5가지Android와 Flutter 앱 개발의 큰 차이점 5가지
Android와 Flutter 앱 개발의 큰 차이점 5가지
 
[1A4]자바스크립트 라이브러리 개발 운영 경험기
[1A4]자바스크립트 라이브러리 개발 운영 경험기[1A4]자바스크립트 라이브러리 개발 운영 경험기
[1A4]자바스크립트 라이브러리 개발 운영 경험기
 
deview2014
deview2014deview2014
deview2014
 
[박민근] 3 d렌더링 옵티마이징_nv_perfhud
[박민근] 3 d렌더링 옵티마이징_nv_perfhud[박민근] 3 d렌더링 옵티마이징_nv_perfhud
[박민근] 3 d렌더링 옵티마이징_nv_perfhud
 
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
 
모니터링 영역의 변천사_클라우드, 디지털 경험까지)
모니터링 영역의 변천사_클라우드, 디지털 경험까지)모니터링 영역의 변천사_클라우드, 디지털 경험까지)
모니터링 영역의 변천사_클라우드, 디지털 경험까지)
 
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101) 모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
모바일 앱 성능 분석 방법 101 (Mobile Application Performance Analysis Methodology 101)
 
기술적 변화를 이끌어가기
기술적 변화를 이끌어가기기술적 변화를 이끌어가기
기술적 변화를 이끌어가기
 
Codex project
Codex projectCodex project
Codex project
 
김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법
 
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
안드로이드 6.0 마시멜로 지원을 고민하는 개발자를 위한 안내서
 
Java performance and trouble shooting
Java performance and trouble shootingJava performance and trouble shooting
Java performance and trouble shooting
 
[123] electron 김성훈
[123] electron 김성훈[123] electron 김성훈
[123] electron 김성훈
 
2일차 20140402
2일차 201404022일차 20140402
2일차 20140402
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
 
Opensource APM SCOUTER in practice
Opensource APM SCOUTER in practiceOpensource APM SCOUTER in practice
Opensource APM SCOUTER in practice
 

More from YoungSu Son

Fault Tolerance 패턴
Fault Tolerance 패턴 Fault Tolerance 패턴
Fault Tolerance 패턴
YoungSu Son
 
Clean Code, Software Architecture, Performance Tuning
Clean Code, Software Architecture, Performance TuningClean Code, Software Architecture, Performance Tuning
Clean Code, Software Architecture, Performance Tuning
YoungSu Son
 
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
YoungSu Son
 
Prototype 패턴 (심만섭)
Prototype 패턴 (심만섭) Prototype 패턴 (심만섭)
Prototype 패턴 (심만섭)
YoungSu Son
 
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
YoungSu Son
 
Singleton 패턴 (김진영 - EVA, 소마에 10기)
Singleton 패턴 (김진영 -  EVA, 소마에 10기) Singleton 패턴 (김진영 -  EVA, 소마에 10기)
Singleton 패턴 (김진영 - EVA, 소마에 10기)
YoungSu Son
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우
YoungSu Son
 
생성 패턴 (강태우 - 소마에 10기)
생성 패턴 (강태우 - 소마에 10기) 생성 패턴 (강태우 - 소마에 10기)
생성 패턴 (강태우 - 소마에 10기)
YoungSu Son
 
초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드 초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드
YoungSu Son
 
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심) DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
YoungSu Son
 
DevOps 시대가 요구하는 품질확보 방법
DevOps 시대가 요구하는 품질확보 방법 DevOps 시대가 요구하는 품질확보 방법
DevOps 시대가 요구하는 품질확보 방법
YoungSu Son
 
클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기
YoungSu Son
 
SW 아키텍처 분석방법
SW 아키텍처 분석방법 SW 아키텍처 분석방법
SW 아키텍처 분석방법
YoungSu Son
 
Android Studio 개발 셋팅 + Genymotion
Android Studio 개발 셋팅 + GenymotionAndroid Studio 개발 셋팅 + Genymotion
Android Studio 개발 셋팅 + Genymotion
YoungSu Son
 
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기) FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
YoungSu Son
 
[NEXT] Flask 로 Restful API 서버 만들기
[NEXT] Flask 로 Restful API 서버 만들기 [NEXT] Flask 로 Restful API 서버 만들기
[NEXT] Flask 로 Restful API 서버 만들기
YoungSu Son
 
[NEXT] GCM을 이용한 게시글 자동 갱신
[NEXT] GCM을 이용한 게시글 자동 갱신[NEXT] GCM을 이용한 게시글 자동 갱신
[NEXT] GCM을 이용한 게시글 자동 갱신
YoungSu Son
 
[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기
YoungSu Son
 
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
YoungSu Son
 
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리) 오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
YoungSu Son
 

More from YoungSu Son (20)

Fault Tolerance 패턴
Fault Tolerance 패턴 Fault Tolerance 패턴
Fault Tolerance 패턴
 
Clean Code, Software Architecture, Performance Tuning
Clean Code, Software Architecture, Performance TuningClean Code, Software Architecture, Performance Tuning
Clean Code, Software Architecture, Performance Tuning
 
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
인공지능 식별추적시스템 실증랩 구축및 운영 - 평가모델 고도화
 
Prototype 패턴 (심만섭)
Prototype 패턴 (심만섭) Prototype 패턴 (심만섭)
Prototype 패턴 (심만섭)
 
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
Chain of Responsibility (심수연 - 소프트웨어 마에스트로 10기)
 
Singleton 패턴 (김진영 - EVA, 소마에 10기)
Singleton 패턴 (김진영 -  EVA, 소마에 10기) Singleton 패턴 (김진영 -  EVA, 소마에 10기)
Singleton 패턴 (김진영 - EVA, 소마에 10기)
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우
 
생성 패턴 (강태우 - 소마에 10기)
생성 패턴 (강태우 - 소마에 10기) 생성 패턴 (강태우 - 소마에 10기)
생성 패턴 (강태우 - 소마에 10기)
 
초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드 초보 개발자/학생들을 위한 오픈소스 트랜드
초보 개발자/학생들을 위한 오픈소스 트랜드
 
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심) DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
DevOps 오픈소스 트랜드 (클라우드, 모바일 중심)
 
DevOps 시대가 요구하는 품질확보 방법
DevOps 시대가 요구하는 품질확보 방법 DevOps 시대가 요구하는 품질확보 방법
DevOps 시대가 요구하는 품질확보 방법
 
클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기
 
SW 아키텍처 분석방법
SW 아키텍처 분석방법 SW 아키텍처 분석방법
SW 아키텍처 분석방법
 
Android Studio 개발 셋팅 + Genymotion
Android Studio 개발 셋팅 + GenymotionAndroid Studio 개발 셋팅 + Genymotion
Android Studio 개발 셋팅 + Genymotion
 
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기) FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
 
[NEXT] Flask 로 Restful API 서버 만들기
[NEXT] Flask 로 Restful API 서버 만들기 [NEXT] Flask 로 Restful API 서버 만들기
[NEXT] Flask 로 Restful API 서버 만들기
 
[NEXT] GCM을 이용한 게시글 자동 갱신
[NEXT] GCM을 이용한 게시글 자동 갱신[NEXT] GCM을 이용한 게시글 자동 갱신
[NEXT] GCM을 이용한 게시글 자동 갱신
 
[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기
 
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
 
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리) 오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
오픈소스 Jedis 리펙토링 하기 (redis java 라이브러리)
 

[NEXT] Android Profiler 사용법

  • 1. 부채  갚기!!                성능  최적화  :  프로파일러  사용기   1
  • 2. Day  6.  부채  갚기!!                성능  최적화  :  프로파일러  사용기   2
  • 4. 학습  목표   • 프로파일러를  통해    성능에  영향을    주는  장애물을      찾아내고,     제거하자.                   • BItmap      이미지      핸들링시    주의    할점을  알수  있다.                                   • AndroId  Garbage  CollectIon  의    내부  동작  원리를  이해  할  수   있다.       • 다양한  Reference를  이해하고,  적절히  사용할수  있다.               4
  • 5. 생각해보기 -­‐ 장애물에는 어떤 것들이 있을까?   1) Out  of  memory   2) Network   3) Low  Battery   4) 100%  CPU  Usage
  • 6. 생각해보기 -­‐ 장애물에는 어떤 것들이 있을까?   1) Out  of  memory   2) Network   3) Low  Battery   4) 100%  CPU  Usage 이번
  • 15. 1. CPU상태 확인하기
 :Traceview  따라하기,  함수/ 클래스별 CPU 실행 시간 확인
 :녹음기 사용하는 것과 비슷(녹음버튼 à 녹음 à 녹음종료버튼 à 녹음확 인)   STEP1.   프로파일 메소드 실행 STEP2.   어플리케이션 동작 STEP3.   프로파일 메소드 종료   분석
  • 16. STEP1.  프로파일 메소드 실행   1)DDMS 선택
  • 17. STEP1.  프로파일 메소드 실행   2) 기기 선택
  • 18. STEP1.  프로파일 메소드 실행   3)Start  Method  Profiling 클릭   : 지금부터 어플리케이션의 모든 동작은 프로파일링 클릭을 하고나면 위와 같은 아이콘으로 변경(동작상태)
  • 19. STEP2.  어플리케이션 동작 ex   :  사진업로드 하는 과정에서 함수/클래스별 CPU사용 시간을 확인   -­‐프로파일 메소드를 실행한 상태에서 확인하고자 하는 동작을 직접 실행
  • 20. STEP3.  프로파일 메소드 종료 분석 Stop  Method  Profiling  를 클릭하면 아래와 같은 분석결과가 팝업
  • 21. STEP3.  프로파일 메소드 종료 분석 1. A)는 CPU를 사용한 메소드/클래스를 시간대 별로 보여줍니다.   2. B)는 전체 CPU사용량을 100%라고 했을 때 각 메소드/클래스의 사용량을
 보여줍니다.   A) B)
  • 22. STEP3.  프로파일 메소드 종료 분석  -­‐  A   1. 시간의 범위를 지정하면 보다 자세히 시간대별 사용량을 볼 수 있습니다.   2. 각 색이 뜻하는 것은 사용량을 나타내는 표(B)의 색과 일치합니다.
 ex)  Dalvik/system/VMDbbug.StargGC  ()
  • 23. STEP3.  프로파일 메소드 종료 분석 -­‐  B   1. 차지하는 비중이 높은 순서대로 정렬합니다.   2. 항목을 클릭하면 Parent와 children으로 구성되어 있습니다.
 ex)  1(android/os/Handler.dipatchMessage)을 기준으로 보면 
 -­‐  Parents(0)는 1을 호출합니다.
 -­‐  Children(2,  39,  120,  1276,  2521)은 1이 호출한 것입니다.
  • 24. 1. 부모가 차지하는 비중에서 자신이 부모에게 차지하는 비중을 곱한 것입니다.     2. 아래의 예시를 통해 보면 2(android/os/Handler/handleCallback)은   부모의 사용량 75% 중에서 86%를 차지했기 때문에 75  X  0.86  =  65.6%가 됩니다.   왜 Percentage의 합이 100%가 아닌지 의문이 생길 수 있습니다.   전체에서 2가 차지하는 비중 부모에서 2가 차지하는 비중 전체에서 부모가 차지하는 비중
  • 25. 100% 60% 30% 10% 부모자식관계 60% 30% 10% 36% 24% 15% 15% 60% 40% 50% 50% 100%  x  60%  x  60%  =  36%100%  x  60%  =  60 100%  x  60%  x  40%  =  24%100%  x  30%  =  30 100%  x  30%  x  50%  =  15% 100%  x  30%  x  50%  =  15% Tree로 나타내면 다음과 같습니다.
  • 26. 따라해보기 1) 본인의 어플리케이션의 시나리오를 만든다.   2) 각 시나리오별 Method  Profiling을 해본다.   3) 시나리오별 CPU를 많이 사용하는 메소드/클래스를 확인한다.
  • 27. 2. 메모리상태 확인하기 STEP1.    Monitor  memory   실행하기 STEP2.   Heap  Dump STEP3.   Allocation Tracker :Android  Studio을  통해  heap의 정보를 얻어서 메모리 상태를 확인 [참고링크]     http://developer.android.com/tools/studio/index.html#git-­‐samples STEP4.   Eclipse MAT
  • 28.   그전에 Android  Memory와 Garbage  collection       (이하 GC)에 대해서 알아보겠습니다.
  • 29. java.lang.OutOfMemoryError:  bitmap  size  exceeds  VM  budget 흔히 발생하는 상황
  • 30. 구글에서   메모리 누수 현상이 자주 발생해서 메모리 관리 체계를 변경합니다. Honeycomb이전 Honeycomb이후 이미지 파일 이전에는  Native영역에서 이미지 파일을 관리했다면,    이후에는 Dalvik내부에서 관리를 하는 구조로 변경되었습니다.   Q  : 이미지파일의 저장위치가 핵심인가요?   A  :  이미지가 메모리 누수의 50~70%를 차지하기 때문에
  • 31. App
  • 32.  
  • 38.  is
  • 41. ‘이미지 저장위치’의 변경만 확인하시고 나머지는   이어서 자세히 설명하겠습니다.   Honey  Comb 이전 Honey  Comb 이후 이미지 저장 위치 Dalvik외부 native  Heap Dalvik 내부 GC 동작 전체 App이 멈춤 부분적으로 진행(partially) Bitmap의 GC GC의 대상이 아님 GC의 대상 다른 App의 영향 메모리 누수가 발생하면 다른 App 도 함께 죽음 다른 앱에 영향이 없음
  • 42. 1) Garbage  Collection(GC)는 사용하지 않는 메모리를 정리하는 것입니다.     2) Mark    Sweep
 -­‐  Mark  :  GC  Roots를 통해서 연결된 객체를 표시(Mark)합니다.    
 -­‐  Sweep  :  Mark되지 않은 객체는 사용하지 않는 객체로 간주하여 삭제(Sweep)합니다. 지금부터 GC에 대해서 알아보겠습니다.
  • 43. 1. GC_CONCURRENT  :  heap영역이 계속 커질 때 새롭게 heap을 확대하지 않고,  
 메모리 회수로 가능한 경우
 2. GC_EXPLICIT  :  System에서 주기적으로 GC를 호출하는 경우
     3. GC_EXTERNAL_MALLOC  :  BITMAP처럼 외부의 메모리를 할당 받은 경우, 하지만 honey-­‐comb 이후 버전부터는 bitmap을 dalvik  heap(internal  heap)에 할당하기 때문에 이전 버전에만 해 당 
 4. GC_FOR_MALLOC  :  heap영역이 가득 찬 경우 전체 어플리케이션을 멈추고 GC를 진행
 5. GC_HPROF_DUMP_HEAP  :  메모리 분석을 위해 HPROF  file을 만든 경우 아래와 같은 이유로 GC가 일어납니다.  
  • 44. Honey  Comb 이전 Honey  Comb 이후 저장 위치 Dalvik외부 native  Heap Dalvik 내부 GC 동작 전체 App이 멈춤 부분적으로 진행(partially) Bitmap의 GC GC의 대상이 아님 GC의 대상 다른 App의 영향 메모리 누수가 발생하면 다른 App 도 함께 죽음 다른 앱에 영향이 없음 1) GC동작 방식
 -­‐  HoneyComb 이전에는 전체 App이 멈추는 Serial  MarkSweep(Stop  the  world)방식이였습니다.
 -­‐ 이후에는  부분적으로 진행하는 Concurrent  MarkSweep으로 변경되었습니다.    
 2) Concurrent  MarkSweep 장점 
 -­‐ 반응성/속도
     부분적으로 동작하기 때문에 앱이 멈추지 않습니다.
     Serial  MarkSweep  :  100ms,  Concurrent  MarkSweep  5ms
 3) Concurrent  MarkSweep 단점
 -­‐ 이전보다 메모리와 CPU를 더 많이 사용하게 되었습니다. 앞에서 본 표입니다.   이번 슬라이드에서는 ‘GC동작 부분’만 확인해보겠습니다.
  • 45. (다른작업도 쓰레드로 진행가능) [출처]  Hello  world  :  Android  앱 메모리 최적화편 Serial  MarkSweep과 Concurrent  MarkSweep 동작 비교
  • 46. 직접 메모리를 관리하고 싶다면, Java에서는 C,  C++에서 사용하는 ‘free’,  ‘delete’가 없기 때문에  주기적으로 혹은 특정 조건일 때 GC 를 하게 됩니다. 이로인해 프로그래머는 메모리 관리에 대해서 고민을 적게 할 수 있습니다.   하지만 임베디드 환경(모바일 포함)에서는 이 메모리 하나 하나가 매우 소중합니다.   예를들어 1회성으로 할당한 공간을  GC과정에서 ‘사용하는 메모리’라고 판단하여 공간을 계속 잡게 될 경우 불필요한 공간낭비로 메무리 누수의 위험이 생길 수 있습니다.  
  • 47. 기본적으로 할당하는 방식은 Strong  Reference입니다. Strong     -­‐  기본적으로 할당하는 방식을 Strong  Reference  라고 부릅니다.
      mLauncher  =  new  Launcher(launcher);     -­‐  GC과정에서 연결된 객체들을 Mark하고 Mark되지 않은 객체들을 Sweep합니다.       즉 메모리 관리에 프로그래머가 신경쓰지 않습니다.    
  • 48. Strong  이외에 3가지가 더 있습니다. 1.  종류 
   Soft  reference,  Weak  reference,  Phantom  reference
     Private  WeakReferenceLauncher  mLauncher;       mLauncher  =  new  WeakReferenceLauncher(launcher);   2. 원리     -­‐  GC동작에서 Strong이 아닌 경우 Mark하지 않고 Reference  Queue라는 공간에 객체를 넣고,  
        Sweep하는 과정에서 제거 Queue에 있는 객체들을 제거 합니다.     3.  차이점     이름에서 느낄 수 있듯이 객체간의 연결정도를 나타냅니다. 그리고 이 연결정도가 강할수록 제거가     되지 않습니다. 객체간의 연결정도를 수식으로 나타내면 Strong    Soft    Weak    Phantom  순서입니다.
  • 49. 더 자세히 보겠습니다.   1. Soft  reference   Mark가 되기도 하고 Reference  Queue에 담기기도 합니다.   Soft  reference로  참조된 객체는 메모리가 절대적으로 부족한 상황이 되기전에는 참조가 유지됩니다.
 각 앱마다 할당된 메모리가 절대적을 부족할 때 그 Reference가 Soft이면 제거, 여유롭다면 Strong과 같이 제거 하지 않습니다.   2.  Weak  reference   Referene  Queue에 담깁니다.   Weak  reference로  참조된 객체는 Soft  Reference보다 더 약한 연결고리를 가집니다.  메모리의 상태와 관계없이 GC가 동작되는 순간  Marked  Object라도 회수됩니다.   Strong Soft Weak Phantom Mark Reference  Queue
  • 50. 3.  Phantom  reference   -­‐  GC가 아닌 코드 내에서 바로 Reference  Queue에 넣습니다.   그렇기 때문에 반드시 Reference  Queue와 함께 사용해야 합니다.   -­‐  Weak  Reference와 유사하며,  finalize 시점에서 메모리를 바로 정리하지 않고 Reference  Queue에 참조를 등 록하여 코드에 접근 할 수 있도록 합니다. 객체의 자원 정리를 구현하기 위해 사용할 수 있습니다.     예제 코드   ReferenceQueue  q  =  new  ReferenceQueue();   PhantomReference  pr  =  new  PhantomReference(object,  referenceQueue);   //  Later  on  another  point   Reference  r  =  q.remove();   //  Now,  clear  up  any  thing  you  want
  • 51. Strong Soft Weak Phantom Mark Reference  Queue 
 -­‐  Strong  :  연결된 객체들을 체크 합니다.
 -­‐  Soft  :  메모리 상태에 따라 Mark하거나,    Reference  Queue에 
   넣습니다.
 -­‐  Weak  :  Reference  Queue에 넣습니다.
 -­‐  Phantom  : 코드상에서 바로 Reference  Queue에 넣습니다. Reference에 따른 Mark과정 차이
  • 52. GC 전 GC 후GC 중 Strong  Reference 동작 방식 기본 컨셉   -­‐ Mark    Sweep  :  GC-­‐Roots로부터 연결된 인스턴스들을 마크합니다. 그리고 마크되지 않은 객체들을 제거 (Sweep)합니다.   -­‐ Reachability  :  Roots로 부터 도달(참조) 가능한 객체(rechable)와 도달 할 수 없는 객체(un  reachable)로 나눕 니다.       -­‐ 프로그래머가 GC에 관여하지 않고 Mark되는 방식에 따라 Mark하고 Mark하지 않은 것들을 Sweep합니다.
  • 53. 마크되는 과정은 아래와 같습니다. Mark  Bit 1 1 1 GC  Roots A B C D E F G H A B C D G F H E 1 D1
  • 54. Mark를 모두 마친 후 제거(Sweep)를 하게 됩니다.   UnmarkedSweep  :  Mark  되지 않은 메모리를 회수합니다. 1 Mark-­‐Bit 1 1 제거 대상
  • 55. GC 전 GC 후GC 중 Soft,  Weak,  Phantom 동작 방식 기본 컨셉   -­‐ Strong과 마찬가지로 Mark    Sweep 방식으로 이루어집니다.   -­‐ 다른 부분은 Mark되지 않는다는 것입니다.
   Soft    :  메모리 상태에 따라 Mark하거나 Reference  Queue에 넣습니다.
   Weak  :  Mark하지 않고  Reference  Queue에 넣습니다.
   Phantom  :  코드상에서 바로 Reference  Queue에 넣습니다.   -­‐ Sweep
   Reference  Queue에 넣어 두었던 객체들을 제거 합니다.
  • 56. Mark  Bit 1 1 1 GC  Roots A B C D E F G H A B C D G F H E 1 이전에 봤던 마크되는 과정입니다.   여기서 Mark된 B객체가 Soft 혹은 Weak  Reference라면?
  • 57. Mark  Bit 1 1 1 GC  Roots A B C D E F G H A B C D G F H E 1 이전에 봤던 마크되는 과정입니다.   여기서 Mark된 B객체가 Soft 혹은 Weak  Reference라면? Reference  Queue B
  • 58. Reference  Queue에 넣은 뒤 제거(Sweep)를 하게 됩니다.   heapSweepSystemWeak  :  Mark하는 과정에서 reference  queue에 넣어두었던 Soft,  Weak,  Phantom   Object의 메모리를 회수합니다.   Reference  Queue a b
  • 59. Strong Soft Weak Phantom Mark Reference  Queue 
 -­‐  Strong  :  연결된 객체들을 체크 합니다.
 -­‐  Soft  :  메모리 상태에 따라 Mark하거나,    Reference  Queue에 
   넣습니다.
 -­‐  Weak  :  Reference  Queue에 넣습니다.
 -­‐  Phantom  : 코드상에서 바로 Reference  Queue에 넣습니다. GC를 다시 한번 정리하면  Mark가 먼저 동작합니다.
  • 60. Mark 후에는 Sweep이 이루어집니다.   3가지 동작이 이루어집니다.
  • 61. 1) heapSweepSystemWeak  :  Mark하는 과정에서 reference  queue에 넣어두었던 Soft,  Weak,   Phantom  Object의 메모리를 회수합니다.   2) BitmapSweep  : 이미지의 메모리를 회수 합니다.   3) UnmarkedSweep  :  Mark  되지 않은 메모리를 회수합니다. Reference  Queue a b 1 Mark-­‐Bit 1 1 제거 대상 Mark 후에는 Sweep이 이루어집니다.  
  • 62. 이미지 객체 회수에 대해서 더 알아보겠습니다.   -­‐ Bitmap은 GC에서 매우 중요한 부분입니다.   -­‐ 메모리 누수의 원인은 대부분 이미지와 관련되어 있습니다.   -­‐ 그래서 안드로이드에서는 Honey  Comb이전과 이후로 Bitmap을 다르게 관리하고 있습니다. Honey  Comb 이전 Honey  Comb 이후 저장 위치 Dalvik외부 native  Heap Dalvik 내부 GC 동작 전체 App이 멈춤 부분적으로 진행(partially) Bitmap의 GC GC의 대상이 아님 GC의 대상 다른 App의 영향 메모리 누수가 발생하면 다른 App도 함께 죽음 다른 앱에 영향이 없음
  • 63. HoneyComb 이전에는 왜 그랬을까요? -­‐ 왜 저장 위치를 밖에 두었을까요?
 Honeycomb이전에는 그래픽 라이브러리를 c++의 skia 라이브러리를 사용했습니다. 그래서 비트맵도 native메모리에 로딩될 수 밖에 없었고, 이를 많이 잡아먹으면 다른 앱에서 사용할 수 없었기 때문에 한계 를 정해 두었습니다.
 

  • 64. HoneyComb 이후 이점은 무엇일까요?     -­‐ 저장 위치를 dalvik  heap으로 bitmap을 옮겼고,  GC를 할때 bitmap도 함께 관리를 할 수 있게 됩니다.
 -­‐ 이전에는 App의 GC가 이루어진다고 해도 bitmap은  native영역에 존재하기 때문에 GC의 대상이 되지 않 았습니다.  bitmap이 native영역을 차지하게 되면 다른 앱을 사용하는데 제약을 받게 됩니다. 이를 해결하 기 위해서는 수동으로 Finalize()와 Recycle()을 통해 직접 native영역에서 메모리를 회수해야 했습니다.
 

  • 65.     이제 메모리를       어떻게 확인하는지 알아봅시다.
  • 66. 2. 메모리상태 확인하기 STEP1.    Monitor  memory   실행하기 STEP2.   Heap  Dump STEP3.   Allocation Tracker :Android  Studio을  통해  heap의 정보를 얻어서 메모리 상태를 확인 [참고링크]     http://developer.android.com/tools/studio/index.html#git-­‐samples STEP4.   Eclipse MAT
  • 67. STEP1.  Monitor Memory 실행하기 Memory 탭을 선택합니다. 어플리케이션  run  상태에서  Android  Studio  하단의  Android  탭을  선택합니다.
  • 68. STEP1.  Monitor Memory 실행하기 or build.gradle의 buildTypes에 debuggable true를 추가합니다. Tools  -­‐  Android  -­‐  Enable  ADB  Integration을  활성화시킵니다. -­‐  실행중인  어플리케이션을  선택할  수  없을  때는? http://stackoverflow.com/questions/26593927/android-­‐studio-­‐no-­‐debuggable-­‐applications
  • 69. STEP1.  Monitor Memory 실행하기 실행  중인  어플리케이션에  할당된  메모리  크기를  확인할  수  있습니다.
  • 70. STEP2.  Dump  HPROF  file   Monitor  Memory에서    Dump  Java  Heap  icon  을  클릭해서   현시점의  Heap의  스냅샷을  생성합니다.
  • 71. STEP2.  Heap  Dump  스냅샷  파일은  Snapshot-­‐yyyy.mm.dd-­‐hh.mm.ss.hprof  이름으로     Captures  탭에  저장되어  있습니다.
  • 72.  스냅샷  파일을  더블클릭하면  아래와  같이  메모리  상태를  확인할  수  있습니다. STEP2.  Heap  Dump
  • 73. 클래스,  인스턴스,  참조트리를  확인할  수  있습니다.     메모리  사용량을  확인하고  메모리  릭  발생지점을  찾는  데  유용합니다. STEP2.  Heap  Dump
  • 74. 분석 전에 몇가지 개념에 대해서 알아보겠습니다.   AC 1. Dominator  Tree  
 -­‐  아래 그림은 Garbage  Collection을 할때 자주 봤던 트리입니다.
 -­‐ 이 트리가  Dominator  Tree입니다.
 -­‐  Dominator  Tree란 객체간 연결을 나타낸 것으로 객체 간의 참조를 보여줍니다.
 
 
 
 
 
 
 2. Shallow  Heap
 -­‐  Object  하나가 가지는 byte를 나타냅니다.
 3. Retain  Heap
 -­‐    GC를 통해 한 Object를 제거 될때 제거되는 총 메모리의 양입니다.
 -­‐  Object가 참조하는 모든 Object의 총 합으로 실질적인 메모리 사용량입니다.   
 -­‐ 예를 들어 A를 제거할 경우 C까지 포함한 메모리의 양을 Retain  Heap이라고 합니다.

  • 75. Reference Tree 탭에서는 연관된 객체들의 Shallow  Heap, Retained  Heap을 보여줍니다. STEP2.  Heap  Dump
  • 76. Instance  탭에서는     Dominator Tree, 객체 정보에 대해서  확인 할 수 있습니다.   STEP2.  Heap  Dump
  • 77. A CB D E 왼쪽과 같은 Dominator Tree를 아래 표로 정리한 입니다. -­‐ A  :  0x42efcad0   -­‐ B  :  0x42d4f4e8   -­‐ C  :  0x42d4f528   -­‐ D  :  0x4248c3c8   -­‐ E  :  0x42d4f510   -­‐ F  :  0x42d4d108   -­‐ G  :  0x42d4f3d8 F G STEP2.  Heap  Dump
  • 78. 스냅샷파일의  우클릭한후  Export  to  standard.hprof  를  클릭하면,   표준  HPORF  파일을  생성할  수  있습니다.   생성된  표준  파일과  Eclipse  MAT를  통해서도  메모리  사용을  분석할  수  있습니다. STEP2.  Heap  Dump [참고영상]     Google  I/O  2011:  Memory  management  for  Android  Apps     https://www.youtube.com/watch?v=_CruQY55HOk
  • 79. STEP3.  Allocation Tracker          Allocation  Tracker  에 대해서 보겠습니다.
  • 80. -­‐    특정 액션을 취했을 때의 메모리 할당의 변화를 관찰하기 위해서 사용합니다. Start  Allocation  Tracking을  눌러  메모 리  할당  모니터링을  시작합니다. STEP3.  Allocation Tracker
  • 81. -­‐    특정 액션을 취했을 때의 메모리 할당의 변화를 관찰하기 위해서 사용합니다. 어플리케이션  내에서  특정  액션을  수행하고,   모니터링  시작할  때  눌렀던  아이콘과  동일한  아이콘을  눌러모니터링을  중지합니다. STEP3.  Allocation Tracker
  • 82. Captures 탭의 Allocation Tracking 폴더에 파일이 생성됩니다. 더블클릭하면 메모리 할당 결과를 확인할 수 있습니다. STEP3.  Allocation Tracker
  • 83. STEP3.  Allocation Tracker 메서드, 클래스 별로 특정한 액션을 취한 후 할당된 메모리량을 확인할 수 있습니다.
  • 84. STEP4.  Eclipse  MAT 1) 2) 다음 슬라이드에 확대된 스크린샷이 있습니다  :D Eclipse  를  실행하여  Plug-­‐in  을  설치합시다.
  • 87. 3) STEP4.  Eclipse  MAT Android  Studio에서  스냅샷을  생성한  후  표준  hprof  파일을  생성합니다. 4) Eclipse DDMS 에서 표준 hprof 파일을 엽니다.
  • 88. Leak  Suspects  :  메모리 누수가 의심되는 곳을 알려줍니다.     간단한 설명과 함께 Details를 통해 자세한 정보를 제공합니다.   STEP4.  Eclipse  MAT
  • 89. Details를 통해 자세한 정보를 보면, 그림과 같이 연관된 객체들의 Shallow  Heap과 Retained  Heap을 보여줍니다. STEP4.  Eclipse  MAT
  • 90. -­‐ 텝 상단에 보면 트리모양의 아이콘이 있습니다.   -­‐ 그 아이콘을 누르면 Dominator  Tree를 확인할 수 있습니다.   STEP4.  Eclipse  MAT
  • 91.   어플리케이션에서 생성된 객체들의 정보에 대해서     확인 할 수 있습니다.   STEP4.  Eclipse  MAT
  • 92. -­‐ 두 개 중 아무 덤프나 클릭 후 아래에 표시된 아이콘을 클릭합니다. A경우에 대한 덤프 B경우에 대한 덤프 STEP4.  Eclipse  MAT
  • 93. -­‐ 생성된 Object들의 크기정보를 표로 보여줍니다.   -­‐ 여기서 상단메뉴 우편에 아이콘을 클릭하면 비교할 대상을 지정할 수 있습니다. STEP4.  Eclipse  MAT
  • 94. -­‐ 비교할 대상을 지정합니다.   STEP4.  Eclipse  MAT
  • 95. -­‐ A  :  Object 각각에 대한 수와 Shallow  heap의 변화를 보여줍니다.     -­‐ B:  전체 Object수 변화와 Shallow  heap의 변화를 보여줍니다.   A B STEP4.  Eclipse  MAT
  • 96. 지금부터 내용은 ‘SUPER’ 중요합니다!   주인공은 마지막에 등장하죠!
  • 97. 안드로이드 앱에서 Memory의 핵심 bitmap!   평균 50%에서 최대 70%까지 차지합니다.
  • 98. 상위 모든 항목이 Bitmap과 관련되어 있습니다!!!!!   핵심은 Bitmap!  Bitmap만 잡자!
  • 99.     1. 이미지 품질 줄이기   2. Bitmap  recycle()  호출   3. Bitmap을 불러올 때 사이즈 줄이기   4. Cache 사용   5. Reference   6. Async 구현 So  what?  그래서 어떻게 하라고 ?
  • 100. 1. 이미지 품질줄이기 res폴더에 이미지 파일을 넣으면 자동으로 손실없이 최적화하게 됩니다.  24비트 이미지더라도 256색 이상 을 사용하지 않았다면 8비트로 파일변환하게 됩니다. 품질은 똑같지만 메모리는 적게 차지하게 됩니다.   하지만 asset  최적화를 하지 않습니다. 그러므로 이미지 품질이 중요하지 않다면 8bit  RGB_565옵션을 권 장합니다.(위의 표에서 볼 수 있듯이 1/4수준)   [오해할 수 있는 부분]   위의 표는 res와 asset의 메모리 사용 비교가 아닙니다. 핵심은 res쪽은 안드로이드에서 최적화를 하니 신 경 쓸 필요가 없고 asset 폴더나 스토리지에 있는 파일은 최적화를 안드로이드에서 하지 않으니 프로그래 머가 ‘알아서’ 조절해야 된다는 겁니다. 품질이 중요하다면 위의 옵션이 아닌 고품질을 유지하고,  중요하지 않다면 옵션을 설정해서 메모리를 줄이는 것이 좋습니다.
  • 101. 2.    Bitmap  recycle()  호출 HoneyComb이후로 bitmap이 GC의 대상이 되기 때문에(처음 들은 것 같다면 background 참고) 참조만 끊어도 GC 이 되지만,  HoneyComb이전 혹은 확실히 하고 싶다면 recycle()을 통해 확실히 하는 것이 좋습니다. Bitmap을 맴버로 선언한 경우
  • 102. 2.    Bitmap  recycle()  호출 HoneyComb이후로 bitmap이 GC의 대상이 되기 때문에(처음 들은 것 같다면 background 참고) 참조만 끊어도 GC 이 되지만,  HoneyComb이전 혹은 확실히 하고 싶다면 recycle()을 통해 확실히 하는 것이 좋습니다. Bitmap을 맴버로 선언하지 않을 경우
  • 103. 3.    Bitmap을 불러올 때 사이즈 줄이기 -­‐ 주의! 불러오고나서가 아니라 부르기 전에 사이즈를 줄여야 합니다.
 àBitmapFactroy.createScaledBitmap()으로  resize하기전에 resize를 하는 것이 좋습니다.   -­‐ BitmapFactory.Option.InSampleSize를 통해 원하는만큼 줄입니다. 실습 : 이미지를 불러오는 ArticleView.java의 소스코드를 수정할 것입니다 아래의 슬라이드부터는 Eclipse 환경에서 작성을 했습니다.
  • 105. 실습
  • 106. -­‐ options.inSampleSize  =  4;  
 읽어올때 사이즈를 줄이는 것입니다.
 여기서 숫자의 의미는  n개의 픽셀을 한 픽셀로 decode 한다는 뜻입니다. 즉 1/n이 줄어들게 됩니다.
 추가로 2의 지수 값을 넣는 것이 decode속도를 가장 높일 수 있는 방법입니다.
 -­‐ Bitmap  resized  =  Bitmap.createScaledBitmap(bitmap,  1000,  1000,  true);
 options.inSampleSize로 크기도 줄어들지만 size도 줄어듭니다.  
 그렇기 때문에 사용할 크기에 맞춰서 resize를 해줘야 합니다.  (bitmap,  width,  height,  filter)   더 알아보기
  • 107. 결과 테스트 : 두개의 사진을 클릭   결과 :  20%절감 (10mega  byte  à 8  mega  byte)
  • 108. 4.    Cache  사용 -­‐ Bitmap이 필요할 때마다 계속 decode하는 것이 아니라 cashe를 통해 저장하여 재사용하는 방법입니다.   -­‐ 캐시의 용량이 커지면 오히려 그 부분에서 메모리 누수가 생길 수 있기 때문에 잘 활용해야 합니다.   -­‐ 안드로이드에서는 메모리케시 (LruCache)와 디스크케시 (DiskCache)를 제공합니다. 실습 : 케시를 사용할 객체를 만들고, 이미지를 불러오는 
   ArticleView.java의 소스코드를 수정할 것입니다.
  • 109. 4.    Cache 사용 –  Cache객체 생성 -­‐ Cache를 사용하는 방법은 다양하게 있습니다.  
 그 중에서 싱글톤으로 인스턴스를 생성하여, 그 인스턴스가 케시에 저장하고 불러오도록 해보겠습니다.   -­‐ Flickr에서 이 방법을 사용하고 있습니다 1.  ImageLoader  객체생성
  • 110.
  • 111. 1. maxMemory  :  현재 메모리를 가져옵니다.   2. cacheSize  :  전체 메모리 중 케시로 사용할 메모리를 정합니다.            mMemoryCache.get(key)  :  케시에서 이미지를 가져옵니다.          mMemoryCache.put(key,  value)  :  케시에 이미지를 저장합니다.
  • 112. 4.    Cache 사용 – 이미지 불러오기에서 사용 *수정할 부분
  • 113. 4.    Cache 사용 – 로그를 통해 Cache동작 확인 1.  처음 이미지를 부를 경우 putCache 2.  같은 이미지를 부를 경우 getCache 실제 코드에 로그 넣기
  • 114. 5.  Reference   -­‐ 아래와 같이 Image를 스크롤로 계속 보여줄 경우 계속 이미지를 메모리에 할당하기 때문에 
 Out  of  Memory가 날 가능성이 높습니다.   -­‐ 이 경우 이미지를 Weak  Reference로 생성하게 된다면 스크롤을 하면서 이전의 할당한 이미 지는 빠르게 GC가 되기 때문에 Out  of  Memory를 방지할 수 있습니다.   스크롤
  • 115. 5.  Reference  :  사용예제     -­‐ ArticleView에서  imageView를  weak  reference로  불러오는  예제입니다.
  • 116. 5.  Reference  :  사용예제  (1)  _  이전코드  
  • 117. 5.  Reference  :  사용예제  (2)  _  수정된  코드      
  • 118. 5.  Reference  :  사용예제  (2)  _  수정된  코드       1. weakReference  변수선언   2. ivImage를  weakReference로  선언  
  • 119. 5.  Reference  :  사용예제  (3)  _  이전  코드      
  • 120. 5.  Reference  :  사용예제  (3)  _  수정된  코드       기존에  ivImage로  쓰던  인스턴스는  imageViewReference.get()으로  사용
  • 121. 6.  Async 1. 필요성
   사진을 읽는 동안 사용자는 아무런 동작도 할 수 없기 때문에
   읽는 시간이 길수록 사용자가 대기해야되는 시간도 길어지게 됩니다.   2. 구현     AsyncTask를 이용해서 멀티쓰레드로 구현합니다.     weakReference로 구현해서 사용자가 다른 창으로 이동하면 GC의 대상으로 바로 포함하게 합니다.
 3. 참고  : 안드로이드 멀티쓰레드     -­‐  안드로이드는 기본적으로 하나의 메인쓰레드가 실행되어 작업을 처리합니다.       -­‐ 메인쓰레드 외 다른쓰레드와의 작업은 핸들러를 통해 통신합니다.     -­‐ 쓰레드를 직접 구현할 경우 동기화 문제로 구현에 어려움이 있기 때문에 
     UI쓰레드와 Background작업을 하나의 클래스(AsyncTask)로 제공합니다.
  • 122. 6.  Async 제공되는 기능 (번호순대로 진행 )   1.  onPreExecute()  :  Background작업 시작전에 UI작업을 진행합니다.
 
   @Override
   protected  void  onPreExecute(){
     super.onPreExecute();     }
 2.  doInBackground()  :  Background 작업을 진행합니다.  
 
   @Override
   Protected  String  doInBackground(String…params){       super.onPreExecute();     }   3.  onPostExecute()  :  Background 작업이 끝난 후 UI 작업을 진행합니다.
 
   @Override
   Protected  void  onPostExecute(String  result){       super.onPreExecute();     }  
  • 123. 6.  Async  –  developer.android  예제 -­‐ 예제코드 :  http://developer.android.com/reference/android/os/AsyncTask.html -­‐ developer.android에 나와있는 예제(아래 링크)로 ProgressDiaolog를 통해 이미지(혹은 파일) 다운로드의
 진행 정도를 보여주는 예제입니다.  
  • 124. 1. onPreExecute()
 -­‐  이 예제에는 사용되지 않았지만 주로 작업전 메세지 알림에 사용됩니다.  Ex)  “다운로드 시작”
 2. doInBackground()
 -­‐ 다운받은 양을 확인하고 사이즈를 리턴하고 이 리턴값은 onPostExecute의 param로 사용합니다.
 3. onPostExecute()
 -­‐ 작업이 완료되면 완료된 작업의 양을 보여줍니다. 3 2 6.  Async  –  developer.android  예제
  • 125. 6.  Async  –  참고예제 1. 참고예제  :  http://makingappfor.blogspot.kr/2013/05/android-­‐asynctask-­‐progressdialog.html   2. developer.android와  마찬가지로  AsyncTask를  사용해서  ProgressDialog에  진행정보로를  갱신하는  예제입니다.
  • 126. 6.  Async  –  참고예제 1. onPreExecute()
 실행전  호출되는  함수로  “작업  시작”이라는  메세지를  알려줍니다.
  • 127. 6.  Async  –  참고예제 2. doInBackground()
 함수가  실행될때  호출되는  함수로  완료된  작업의  수를  return  값으로  넘깁니다.
  • 128. 6.  Async  –  참고예제 3. onPostExecute()
 doInBackground  함수가  종료되면  실행되는  함수로  doInBackground함수가  return값으로   보낸  작업완료  수를  화면에  표시합니다.
  • 129. [참고자료]   1. Google  I/O  2011:Memory  management  for  Android  Apps  :  http://www.youtube.com/watch?v=_CruQY55HOk   2. Android  Developers  :  http://developer.android.com/   3. Hello  world  :  Android  앱 메모리 최적화편  :  http://helloworld.naver.com/helloworld/539525#sec1_5   4. 초보코딩왕의 Power  Dev  안드로이드 메모리관리 :  http://ccdev.tistory.com/2   5. asyncTask  예제  :  http://makingappfor.blogspot.kr/2013/05/android-­‐asynctask-­‐progressdialog.html