Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Brief History of Memory Leaks

mvndy_hd
November 07, 2020

A Brief History of Memory Leaks

Based on the book Programming Android in Kotlin, we get into the weeds exploring Android memory and threading and how memory leaks have influenced the evolution of development.

mvndy_hd

November 07, 2020
Tweet

More Decks by mvndy_hd

Other Decks in Technology

Transcript

  1. Timeline JetBrains: Coroutines are like light-weight threads 2017 Roman Elizarov

    [JB]: Coroutines in Practice 2018 Roman Elizarov [JB]: Structured Concurrency 2019
  2. Timeline JetBrains: Coroutines are light-weight threads 2017 Roman Elizarov [JB]:

    Coroutines in Practice 2018 2009 Android Developer Blog: Avoiding memory leaks 2019 Roman Elizarov: Structured Concurrency
  3. Timeline JetBrains: Coroutines are light-weight threads 2017 Roman Elizarov [JB]:

    Coroutines in Practice 2018 2009 Android Developer Blog: Avoiding memory leaks 2016 KT-1622: Coroutine does not clear internal state Fixed Kotlin 1.4 2019 Roman Elizarov: Structured Concurrency
  4. Why do memory leaks matter? • Android has very limited

    resources in hardware capacity ◦ ~15% of Android users use Lollipop and below on their devices¹ • Memory leaks can cause "jank", OOM, and other strange behaviors ¹ Bradshaw, Kyle. “Google Kills Android Distribution Numbers on the Web - 9to5Google.” 9To5Google
  5. What is a memory leak? • When the heap holds

    to allocated memory longer than necessary • When an object is allocated in memory but is unreachable for the running program
  6. Memory management in Android and the JVM The Java heap,

    thread-local allocations, and garbage collection (GC)
  7. Physical & virtual memory management • Android tries to share

    RAM pages across several processes via paging. • At application initialization, a program in the OS called Zygote forks a new VM instance. • The VM creates a store for dynamic memory allocation called the heap. ◦ A shared store for all pages to be temporarily stored in memory
  8. Java Heap • Every application has its own process and

    heap ◦ If your app reaches heap capacity and tries to allocate for more memory, it will receive an OOM • The ART heap organizes objects by age and size ◦ Younger Generation (minor) ◦ Older Generation (major) ◦ Permanent Generation (major)
  9. Garbage collection (GC) • Mechanism for reclaiming unused memory within

    a self-managed memory environment • Will free allocated memory back to the heap • GC will: ◦ Find data objects in a program that cannot be reached in the future ◦ Reclaim the resources used by those objects • Objects eligible for GC: ◦ Nullifying the object reference ◦ Re-assigning the object reference ◦ Object created inside method
  10. Thread Local Allocations • ART memory management also has thread-local

    allocations • Grouped by regions (or threads) • No one region can access an object within another region
  11. Key Takeaways • Any time Android hardware components are used,

    there is battery drainage. ◦ Excessive paging swaps, checks, clears ◦ Camera, location, graphics, wifi radio • GC will help manage the heap, but too many calls for GC can block the UI ◦ Be frugal with memory allocation! • Too much memory consumption can lead to "jank", OutOfMemory exceptions, and other strange behaviors
  12. Android Main (UI) Thread • Interacts and manipulates UI widgets

    and views • Allows Android components in the application to interact with the Android OS • All components run within the same process instantiates on the UI thread
  13. Key Takeaways: • Every Android component (Activity, Service, Broadcast Intent,

    etc) has a lifecycle of its own • Killing an Activity or even the UI Thread does not necessarily kill a background thread • Do not block the UI thread! • Do not access the UI toolkit from outside the UI Thread • Force the top-level activity/fragment to be the sole system responsible for updating UI objects
  14. • Making an explicit references if you accidentally inject an

    Android Activity or Context or View or another Android UI toolkit component into background threading • Holding an activity or view or context as a static reference Explicit Memory Leaks class AlertDialogCreator(val context: Context) { companion object { fun buildDialog(context: Context, title: String, positive: String) = AlertDialog.Builder(context) .setPositiveButton(positive, null) .show() } }
  15. Timeline JetBrains: Coroutines are light-weight threads 2017 Roman Elizarov [JB]:

    Coroutines in Practice 2018 2009 Android Developer Blog: Avoiding memory leaks 2016 KT-1622: Coroutine does not clear internal state Fixed Kotlin 1.4 2019 Roman Elizarov: Structured Concurrency Android deprecates AsyncTask
  16. Timeline JetBrains: Coroutines are light-weight threads 2017 JetBrains: Every running

    coroutine consumes resources 2019 2009 Android Developer Blog: Avoiding memory leaks 2016 KT-1622: Coroutine does not clear internal state Fixed Kotlin 1.4 Google deprecates AsyncTask
  17. Implicit Memory Leaks: Async Tasks class MainActivity : Activity {

    /*removed for brevity */ inner class SomeAsyncTask: AsyncTask<Void, Void, String> { override fun doInBackground( ) { /*removed for brevity */ } override fun onPostExecute(results: String): String { /* removed for brevity */ } }
  18. WeakReferences? class SomeAsyncTask(val activity: MainActivity): AsyncTask<Void, Void, String> { var

    reference: WeakReference<MainActivity> = WeakReference(activity) override fun doInBackground( ) { /*removed for brevity */ } override fun onPostExecute(results: String): String { /* removed for brevity */ } }
  19. Implicit Memory Leaks: Fragment Views • The Fragment's View (but

    not the Fragment itself) is destroyed when a Fragment is put on the backstack² ◦ Developers are expected to clear refs for views in Fragment::onDestroyView • Be wary of third-party libraries that may reference the use of an Android resource ¹ “Issue 145468285: Memory Leak with Nested Fragments and Data Binding.” Issuetracker.google.com, Google, 2 Dec. 2019, 09:01am PT, issuetracker.google.com/issues/145468285#comment6.
  20. Avoiding potential Memory Leaks • Profile your code and how

    you interact with the Android API Framework • Follow the constraints of the Android threading model • Profile your app with AS or LeakCanary • Ask yourself "could I be interacting with a hardware component"? ◦ Databases, networking, Android graphics, location, etc etc
  21. Avoiding potential Memory Leaks • Pay special care to static

    references, since they are stored longest in heap ◦ Never store Android components like Activities, Services, views, etc. • Do not reference Activities/Views/Fragments/Context and other Android components outside the UI thread • Use Glide if you can, but if you have to work with bitmaps, make sure to recycle/nullify • Avoid the use of persistent services whenever possible
  22. Sources cited: 1. Bradshaw, Kyle. “Google Kills Android Distribution Numbers

    on the Web - 9to5Google.” 9To5Google, Google, 10 Apr. 2020, 8:35am PT, 9to5google.com/2020/04/10/google-kills-android-distribution-numbers-web/. 2. “Issue 145468285: Memory Leak with Nested Fragments and Data Binding.” Issuetracker.google.com, Google, 2 Dec. 2019, 09:01am PT, issuetracker.google.com/issues/145468285#comment6. 3. Laurence, Pierre. TrekMe. Github. https://github.com/peterLaurence/TrekMe