Vous êtes sur la page 1sur 43

Memory Management for Android Apps

Patrick Dubroy (dubroy.com · @dubroy) May 11, 2011

Memory Management for Android Apps Patrick Dubroy ( dubroy.com · @dubroy ) May 11, 2011
3 192MB RAM

3

192MB RAM

3 192MB RAM
4 1GB RAM

4

1GB RAM

4 1GB RAM

Xoom

1280x800

G1

320x480

5

Xoom 1280x800 G1 320x480 5

6

6

Sof tware

Work expands to fill the time available.

7

memory

Sof tware Work expands to fill the time available. 7 memory

Overview

• Changes in Gingerbread and Honeycomb

– heap size

– GC

– bitmaps

• Understanding heap usage

– logs

– memory leaks

– Eclipse Memory Analyzer (MAT)

8

heap size – GC – bitmaps • Understanding heap usage – logs – memory leaks –

Expectations

• Android

• Dalvik heap

• Garbage collection

• OutOfMemoryError

9

Expectations • Android • Dalvik heap • Garbage collection • OutOfMemoryError 9

Heap Size

• Heap size limits

– G1: 16MB

– Droid: 24MB

– Nexus One: 32MB

– Xoom: 48MB

• ActivityManager.getMemoryClass()

10

Heap size limits – G1: 16MB – Droid: 24MB – Nexus One: 32MB – Xoom: 48MB

Large Heaps

• Honeycomb adds “largeHeap” option in AndroidManifest.xml:

Degrades performance!

Use only if you understand why you need it.

<application

android:name="com.example.foobar"

android:largeHeap="true"

</application>

ActivityManager.getLargeMemoryClass()

11

android:largeHeap="true" </application> ActivityManager.getLargeMemoryClass() 11

Garbage Collection

GC Roots
GC Roots
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12

12

Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12
Garbage Collection GC Roots 12

Garbage Collection

GC Roots
GC Roots
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13

13

Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13
Garbage Collection GC Roots 13

Garbage Collection

GC Roots
GC Roots
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14

14

Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14
Garbage Collection GC Roots 14

Garbage Collection

GC Roots
GC Roots
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15

15

Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15
Garbage Collection GC Roots 15

Garbage Collection

• Bigger heaps = longer pauses?

• Pre-Gingerbread GC:

– Stop-the-world

– Full heap collection

– Pause times often > 100ms

• Gingerbread and beyond:

– Concurrent (mostly)

– Partial collections

– Pause times usually < 5ms

16

100ms • Gingerbread and beyond: – Concurrent (mostly) – Partial collections – Pause times usually <

Bitmaps

Old way (pre-Honeycomb):

freed via recycle() or finalizer hard to debug full, stop-the-world GCs

17

– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed
– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed
– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed
– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed

Managed

Native

– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed
– freed via recycle() or finalizer – hard to debug – full, stop-the-world GCs 17 Managed

Bitmaps

Old way (pre-Honeycomb):

freed via recycle() or finalizer

hard to debug

full, stop-the-world GCs

– hard to debug – full, stop-the-world GCs Managed New way: – freed synchronously by GC
– hard to debug – full, stop-the-world GCs Managed New way: – freed synchronously by GC

Managed

New way:

freed synchronously by GC

easier to debug

concurrent & partial GCs

18

Native

GCs Managed New way: – freed synchronously by GC – easier to debug – concurrent &

Overview

• Changes in Gingerbread and Honeycomb

– heap size

– GC

– bitmaps

• Understanding heap usage

– logs

– memory leaks

– Eclipse Memory Analyzer (MAT)

19

heap size – GC – bitmaps • Understanding heap usage – logs – memory leaks –

Overview

• Changes in Gingerbread and Honeycomb

– heap size

– GC

– bitmaps

• Understanding heap usage

– logs

– memory leaks

– Eclipse Memory Analyzer (MAT)

20

heap size – GC – bitmaps • Understanding heap usage – logs – memory leaks –

Interpreting Log Messages

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/ 9991K, external 4703K/5261K, paused 2ms+2ms

21

Log Messages D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/ 9991K, external 4703K/5261K, paused 2ms+2ms 21

Interpreting Log Messages

D/dalvikvm( 9050):

GC_CONCURRENT

freed 2049K, 65% free 3571K/

9991K, external 4703K/5261K, paused 2ms+2ms

• Reason for GC

– GC_CONCURRENT

– GC_FOR_MALLOC

– GC_EXTERNAL_ALLOC

– GC_HPROF_DUMP_HEAP

– GC_EXPLICIT

22

• Reason for GC – GC_CONCURRENT – GC_FOR_MALLOC – GC_EXTERNAL_ALLOC – GC_HPROF_DUMP_HEAP – GC_EXPLICIT 22

Interpreting Log Messages

D/dalvikvm( 9050): GC_CONCURRENT

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/ 9991K, external 4703K/5261K, paused 2ms+2ms

freed 2049K, 65% free 3571K/

9991K, external 4703K/5261K, paused 2ms+2ms

• Reason for GC • Amount freed

23

freed 2049K, 65% free 3571K/ 9991K, external 4703K/5261K, paused 2ms+2ms • Reason for GC • Amount

Interpreting Log Messages

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K,

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 9991K, external 4703K/5261K, paused 2ms+2ms 65% free 3571K/

9991K, external 4703K/5261K, paused 2ms+2ms

65% free 3571K/

• Reason for GC

• Amount freed

• Heap statistics

24

9991K, external 4703K/5261K, paused 2ms+2ms 65% free 3571K/ • Reason for GC • Amount freed •

Interpreting Log Messages

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/

9991K,

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/ 9991K, external 4703K/5261K, paused 2ms+2ms

external 4703K/5261K, paused 2ms+2ms

• Reason for GC

• Amount freed

• Heap statistics

• External memory statistics

25

4703K/5261K, paused 2ms+2ms • Reason for GC • Amount freed • Heap statistics • External memory

Interpreting Log Messages

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/

9991K, external 4703K/5261K,

paused 2ms+2ms

• Reason for GC

• Amount freed

• Heap statistics

• External memory statistics

• Pause time

26

paused 2ms+2ms • Reason for GC • Amount freed • Heap statistics • External memory statistics

Heap Dumps

• Binary dump of all objects

• Create with:

– DDMS

android.os.Debug.dumpHprofData()

• Convert to standard HPROF format:

hprof-conv orig.hprof converted.hprof

• Analyze with MAT, jhat, etc.

27

• Convert to standard HPROF format: hprof-conv orig.hprof converted.hprof • Analyze with MAT, jhat, etc. 27

Memory Leaks

• GC does not prevent leaks!

• Leak: ref to an unused object preventing GC

• References to Activity (Context)

– View, Drawable,

28

prevent leaks! • Leak: ref to an unused object preventing GC • References to Activity (Context)

Memory Leaks

Activity
Activity

ViewGroup

Views

29

Memory Leaks Activity ViewGroup Views 29
Memory Leaks Activity ViewGroup Views 29
Memory Leaks Activity ViewGroup Views 29
Memory Leaks Activity ViewGroup Views 29

Eclipse Memory Analyzer (MAT)

• Download from http://eclipse.org/mat/

• “Shallow heap” and “retained heap”

30

(MAT) • Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 30 100 100 100 100
(MAT) • Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 30 100 100 100 100
100 100 100
100
100
100
100
100
(MAT) • Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 30 100 100 100 100
(MAT) • Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 30 100 100 100 100

Eclipse Memory Analyzer (MAT)

• Download from http://eclipse.org/mat/

• “Shallow heap” and “retained heap”

31

• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 31 100 100 100 R =
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 31 100 100 100 R =
100 100 100
100
100
100

R = 100

100
100
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 31 100 100 100 R =
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 31 100 100 100 R =

Eclipse Memory Analyzer (MAT)

• Download from http://eclipse.org/mat/

• “Shallow heap” and “retained heap”

32

• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 32 R = 100 100 100
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 32 R = 100 100 100

R = 100

100 100 100
100
100
100
100
100
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 32 R = 100 100 100
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 32 R = 100 100 100

Eclipse Memory Analyzer (MAT)

• Download from http://eclipse.org/mat/

• “Shallow heap” and “retained heap”

33

• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 33 100 100 R = 400
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 33 100 100 R = 400
100 100
100
100

R = 400

100
100
100
100
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 33 100 100 R = 400
• Download from http://eclipse.org/mat/ • “Shallow heap” and “retained heap” 33 100 100 R = 400

Dominator Tree

• Dominator: closest object on every path to node

34

A B D A B C D C E E
A
B
D
A
B
C
D
C
E
E

Demo: Debugging a memory leak with MAT

Demo: Debugging a memory leak with MAT

public class MainActivity extends Activity implements ActionBar.TabListener {

static Leaky leak = null;

class Leaky { void doSomething() { System.out.println("Wheee!!!");

}

}

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

if (leak == null) { leak = new Leaky();

}

36

( Bundle savedInstanceState) { super . onCreate(savedInstanceState); if (leak == null ) { leak = new

public class MainActivity extends Activity implements ActionBar.TabListener {

static Leaky leak = null;

class Leaky { void doSomething() { System.out.println("Wheee!!!");

}

}

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

if (leak == null) { leak = new Leaky();

}

37

onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (leak == null) { leak = new Leaky(); } 37

public class MainActivity extends Activity implements ActionBar.TabListener {

static Leaky leak = null;

class Leaky { void doSomething() { System.out.println("Wheee!!!");

}

}

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

if (leak == null) { leak = new Leaky();

}

38

onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (leak == null) { leak = new Leaky(); } 38

public class MainActivity extends Activity implements ActionBar.TabListener {

static Leaky leak = null;

class Leaky { void doSomething() { System.out.println("Wheee!!!");

}

}

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

if (leak == null) { leak = new Leaky();

}

39

savedInstanceState) { super.onCreate(savedInstanceState); if (leak == null ) { leak = new Leaky (); } 39

40

40 MainActivity Leaky MainActivity class

MainActivity

40 MainActivity Leaky MainActivity class

Leaky

40 MainActivity Leaky MainActivity class

MainActivity

class

40 MainActivity Leaky MainActivity class

Demo: Debugging a memory leak with MAT

Demo: Debugging a memory leak with MAT

Memory Leaks

• References to Activity, Context, View, Drawable,

• Non-static inner classes (e.g. Runnable)

• Caches

42

Leaks • References to Activity, Context, View, Drawable, • Non-static inner classes (e.g. Runnable) • Caches

Links

• Articles on Android Developers Blog

Avoiding Memory Leaks by Romain Guy

• Eclipse Memory Analyzer: http://www.eclipse.org/mat/

• Markus Kohler ʼ s Java Performance Blog: http://kohlerm.blogspot.com/

• Feedback on this talk:

43

Blog: http://kohlerm.blogspot.com/ • Feedback on this talk: http://speakermeter.com/talks/memory-management-android 43