Effective Memory
Management
Denis Zhuchinski
Agenda
● Android Memory Management
● Memory Leaks
● Tools
● Demo
● How to avoid OutOfMemoryError?
Android Memory Management
Android Memory Management
● No swap space
● Virtual Address Space
● Paging and Memory-Mapping (mmapping)
Application Memory Regions
● Heap
○ Java
○ Native
● Stack
● Shared Memory
Sharing Memory
● Each app process is forked from an existing process called Zygote
● Most static data is mmapped into a process (Dalvik code, app resources,
native code)
● Android shares the same dynamic RAM across processes using explicitly
allocated shared memory regions (ashmem or gralloc)
Application Memory Restrictions
● Isolated in process
● Hard limit heap size
● Heap size limit varies between devices
● Proportional Set Size (PSS): Clean, Dirty
● ActivityManager.getMemoryClass()
● ActivityManager.getLargeMemoryClass()
Process Priority
Activity Process
Visible Process
Started Service
Process
Background
Process
Empty Process
Critical Priority
High Priority
Low Priority
Main Process Memory Areas
- Stack (method invocation, local variables)
- Heap (all objects)
● java.lang.StackOverFlow
● java.lang.OutOfMemoryError
Main Process Memory Areas
- Stack (method invocation, local variables)
- Heap (all objects)
● java.lang.StackOverFlowError
● java.lang.OutOfMemoryError
Are there memory leaks in Android? Isn’t Java a garbage-collected language?
Garbage Collection
● Dalvik and ART performs routine garbage collection (GC)
● Uses mark-and-sweep algorithm
● All objects created with new are stored on the heap
ART GC Enhancement
● Enumerates all allocated objects and marks all reachable objects in only one
pause while Dalvik’s GC pauses twice
● Parallelization
● Lower total GC time (cleaning up recently-allocated)
● Compacting GC merges freed-up single blocks in one location of memory
(Still in development by Android Open-Source Project)
ART GC Enhancement
Memory Leaks
● Memory leak is a situation where some objects are not used by application
any more, but GC fails to recognize them as unused
● Degradation in performance as the memory consumption increases
Memory Leaks
How to detect?
● App crashes with an java.lang.OutOfMemmoryError (OOM)
● Frequent GC calls in LogCat before the crash
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
07-02 15:56:14.275: D/dalvikvm(30615): GC_FOR_ALLOC freed 4442K, 25% free 20183K/26856K, paused 24ms, total 24ms
07-02 15:56:16.785: I/dalvikvm-heap(30615): Grow heap (frag case) to 38.179MB for 8294416-byte allocation
07-02 15:56:17.225: I/dalvikvm-heap(30615): Grow heap (frag case) to 48.279MB for 7361296-byte allocation
07-02 15:56:17.625: I/Choreographer(30615): Skipped 35 frames! The application may be doing too much work on its main thread.
07-02 15:56:19.035: D/dalvikvm(30615): GC_CONCURRENT freed 35838K, 43% free 51351K/89052K, paused 3ms+5ms, total 106ms
I/art: <GC_Reason> <GC_Name> <Objects_freed>(<Size_freed>) AllocSpace Objects, Large_objects_freed>
(<Large_object_size_freed>) <Heap_stats> LOS objects, <Pause_time(s)>
07-01 16:00:44.531: I/art(198): Explicit concurrent mark sweep GC freed 700(30KB) AllocSpace objects, 0(0B) LOS objects, 792% free,
18MB/21MB, paused 186us total 12.763ms
07-01 16:00:44.545: I/art(198): Explicit concurrent mark sweep GC freed 7(240B) AllocSpace objects, 0(0B) LOS objects, 792% free,
18MB/21MB, paused 198us total 9.465ms
07-01 16:00:44.554: I/art(198): Explicit concurrent mark sweep GC freed 5(160B) AllocSpace objects, 0(0B) LOS objects, 792% free,
18MB/21MB, paused 224us total 9.045ms
Tools
Tools
● adb shell dumpsys meminfo <package_name | pid>
● Android Monitor
○ Allocation Tracker
○ Heap Dump
● Eclipse Memory Analyzer Tool (MAT)
● LeakCanary (Square)
Demo
https://github.com/zhuchinskyi/MemoryLeakSample.git
● Do not keep long-lived references to an Activity, Context, View, Drawable...
● Avoid non-static inner classes in an activity if you don’t control their life cycle
● Use Soft and Weak References
● Try to not have long living objects
● Use as much as possible application Context instead of Activity
● Remember to call unregisterReceiver() after calling registerReceiver()
● Implement cancellation policies for background threads
● Keep track of your references
● Keep an eye on the heap while the app is running
● Don’t assume GC will clean up all for you!
● Search for memory leaks even when things aren't failing!
How to avoid Memory Leaks?
● Use bitmaps with correct resolution
● Recycle the bitmaps more often, instead of just onDestroy()
● Send large files to server by chunks
● Avoid creating unnecessary objects
● Check the available heap of your application
● Coordinate with the system by implementing onTrimMemory() callback
● External libraries should be used carefully
● Use Proguard and zipalign
How to avoid OutofMemoryError?
References
- https://xakep.ru/2014/05/21/excurse-in-android-architecture/
- https://software.intel.com/en-us/android/articles/art-vs-dalvik-introducing-the-new-
android-x86-runtime
- https://software.intel.com/en-us/android/articles/tips-for-optimizing-android-application-
memory-usage
- https://android.googlesource.com/platform/art/+/master/runtime/gc/
- http://developer.android.com/intl/ru/tools/debugging/debugging-memory.html
- http://www.raizlabs.com/dev/2014/03/wrangling-dalvik-memory-management-in-
android-part-1-of-2/
- https://acadgild.com/blog/analyze-manage-android-devices-memory-allocation-through-
ddms-mat/
- http://developer.android.com/intl/ru/tools/help/am-memory.html
Q&A

Effective memory management

  • 1.
  • 2.
    Agenda ● Android MemoryManagement ● Memory Leaks ● Tools ● Demo ● How to avoid OutOfMemoryError?
  • 3.
  • 4.
    Android Memory Management ●No swap space ● Virtual Address Space ● Paging and Memory-Mapping (mmapping)
  • 5.
    Application Memory Regions ●Heap ○ Java ○ Native ● Stack ● Shared Memory
  • 6.
    Sharing Memory ● Eachapp process is forked from an existing process called Zygote ● Most static data is mmapped into a process (Dalvik code, app resources, native code) ● Android shares the same dynamic RAM across processes using explicitly allocated shared memory regions (ashmem or gralloc)
  • 7.
    Application Memory Restrictions ●Isolated in process ● Hard limit heap size ● Heap size limit varies between devices ● Proportional Set Size (PSS): Clean, Dirty ● ActivityManager.getMemoryClass() ● ActivityManager.getLargeMemoryClass()
  • 8.
    Process Priority Activity Process VisibleProcess Started Service Process Background Process Empty Process Critical Priority High Priority Low Priority
  • 9.
    Main Process MemoryAreas - Stack (method invocation, local variables) - Heap (all objects) ● java.lang.StackOverFlow ● java.lang.OutOfMemoryError
  • 10.
    Main Process MemoryAreas - Stack (method invocation, local variables) - Heap (all objects) ● java.lang.StackOverFlowError ● java.lang.OutOfMemoryError
  • 11.
    Are there memoryleaks in Android? Isn’t Java a garbage-collected language?
  • 12.
    Garbage Collection ● Dalvikand ART performs routine garbage collection (GC) ● Uses mark-and-sweep algorithm ● All objects created with new are stored on the heap
  • 13.
    ART GC Enhancement ●Enumerates all allocated objects and marks all reachable objects in only one pause while Dalvik’s GC pauses twice ● Parallelization ● Lower total GC time (cleaning up recently-allocated) ● Compacting GC merges freed-up single blocks in one location of memory (Still in development by Android Open-Source Project)
  • 14.
  • 15.
  • 16.
    ● Memory leakis a situation where some objects are not used by application any more, but GC fails to recognize them as unused ● Degradation in performance as the memory consumption increases Memory Leaks
  • 17.
    How to detect? ●App crashes with an java.lang.OutOfMemmoryError (OOM) ● Frequent GC calls in LogCat before the crash D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time> 07-02 15:56:14.275: D/dalvikvm(30615): GC_FOR_ALLOC freed 4442K, 25% free 20183K/26856K, paused 24ms, total 24ms 07-02 15:56:16.785: I/dalvikvm-heap(30615): Grow heap (frag case) to 38.179MB for 8294416-byte allocation 07-02 15:56:17.225: I/dalvikvm-heap(30615): Grow heap (frag case) to 48.279MB for 7361296-byte allocation 07-02 15:56:17.625: I/Choreographer(30615): Skipped 35 frames! The application may be doing too much work on its main thread. 07-02 15:56:19.035: D/dalvikvm(30615): GC_CONCURRENT freed 35838K, 43% free 51351K/89052K, paused 3ms+5ms, total 106ms I/art: <GC_Reason> <GC_Name> <Objects_freed>(<Size_freed>) AllocSpace Objects, Large_objects_freed> (<Large_object_size_freed>) <Heap_stats> LOS objects, <Pause_time(s)> 07-01 16:00:44.531: I/art(198): Explicit concurrent mark sweep GC freed 700(30KB) AllocSpace objects, 0(0B) LOS objects, 792% free, 18MB/21MB, paused 186us total 12.763ms 07-01 16:00:44.545: I/art(198): Explicit concurrent mark sweep GC freed 7(240B) AllocSpace objects, 0(0B) LOS objects, 792% free, 18MB/21MB, paused 198us total 9.465ms 07-01 16:00:44.554: I/art(198): Explicit concurrent mark sweep GC freed 5(160B) AllocSpace objects, 0(0B) LOS objects, 792% free, 18MB/21MB, paused 224us total 9.045ms
  • 18.
  • 19.
    Tools ● adb shelldumpsys meminfo <package_name | pid> ● Android Monitor ○ Allocation Tracker ○ Heap Dump ● Eclipse Memory Analyzer Tool (MAT) ● LeakCanary (Square)
  • 20.
  • 21.
    ● Do notkeep long-lived references to an Activity, Context, View, Drawable... ● Avoid non-static inner classes in an activity if you don’t control their life cycle ● Use Soft and Weak References ● Try to not have long living objects ● Use as much as possible application Context instead of Activity ● Remember to call unregisterReceiver() after calling registerReceiver() ● Implement cancellation policies for background threads ● Keep track of your references ● Keep an eye on the heap while the app is running ● Don’t assume GC will clean up all for you! ● Search for memory leaks even when things aren't failing! How to avoid Memory Leaks?
  • 22.
    ● Use bitmapswith correct resolution ● Recycle the bitmaps more often, instead of just onDestroy() ● Send large files to server by chunks ● Avoid creating unnecessary objects ● Check the available heap of your application ● Coordinate with the system by implementing onTrimMemory() callback ● External libraries should be used carefully ● Use Proguard and zipalign How to avoid OutofMemoryError?
  • 23.
    References - https://xakep.ru/2014/05/21/excurse-in-android-architecture/ - https://software.intel.com/en-us/android/articles/art-vs-dalvik-introducing-the-new- android-x86-runtime -https://software.intel.com/en-us/android/articles/tips-for-optimizing-android-application- memory-usage - https://android.googlesource.com/platform/art/+/master/runtime/gc/ - http://developer.android.com/intl/ru/tools/debugging/debugging-memory.html - http://www.raizlabs.com/dev/2014/03/wrangling-dalvik-memory-management-in- android-part-1-of-2/ - https://acadgild.com/blog/analyze-manage-android-devices-memory-allocation-through- ddms-mat/ - http://developer.android.com/intl/ru/tools/help/am-memory.html
  • 24.