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

Demystifying Memory Leaks in Android

Demystifying Memory Leaks in Android

Memory leaks can silently sabotage the performance and stability of Android applications, posing a significant challenge for developers. Memory leaks can be a silent and persistent performance killer. In this talk we will explore the causes, symptoms, and consequences of memory leaks, shedding light on how they can gradually degrade the user experience and impact device performance.

Yves Kalume

July 29, 2023
Tweet

More Decks by Yves Kalume

Other Decks in Programming

Transcript

  1. Tech communities journey • Started since 2019 • GDSC Lead

    2021 • GDG Co-organizer 2022 • GDE for Android April 2023 ❤ Social impact (Devscast, Soracert)
  2. Memory management Management applied to computer memory • allocate portions

    of memory to programs at their request • free it for reuse when no longer needed.
  3. #include <stdlib.h> void performOperations() { int* data = malloc(sizeof(int)); //

    Some operations on 'data'//. free(data); // Memory is properly freed } int main() { performOperations(); return 0; }
  4. Memory leak When allocated memory is not released once it

    has been used (and is no longer useful).
  5. #include <stdlib.h> void performOperations() { int* data = malloc(sizeof(int)); //

    Some operations on 'data'//. // Memory is not freed } int main() { performOperations(); return 0; }
  6. Memory on the JVM • We are not required to

    implement memory management logic • Garbage collector • Object of our program are stored in the Heap • If the heap is full, you’ll get an OutOfMemoryError.
  7. class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    ... val textView = findViewById<TextView>(R.id.myTextView) MySingleton.leakedView = textView } } object MySingleton { var leakedView: View? = null }
  8. class MyActivity : AppCompatActivity() { ... override fun onDestroy() {

    super.onDestroy() MySingleton.leakedView = null } } object MySingleton { var leakedView: View? = null }
  9. Detect retained objects • Determine the circumstances in which an

    object must be collected E.g : Activity onDestroy is called • Wait few seconds (5)
  10. class App : Application() { private val lifecycleCallbacks = object

    : Application.ActivityLifecycleCallbacks { ... override fun onActivityDestroyed(activity: Activity) { shouldBeCollected.add(WeakReference<Activity>(activity)) } } override fun onCreate() { super.onCreate() this.registerActivityLifecycleCallbacks(lifecycleCallbacks) } }
  11. Heap dump a snapshot of your application's memory in a

    point in time. • What types of objects your app has allocated, and how many of each. • How much memory each object is using. • Where references to each object are being held in your code.
  12. Analyzing the heap • Parses the .hprof file • Locates

    retained objects in that heap dump. • Finds the path of references • Produce leak trace.
  13. Some advices • Pay attention while using reference of activity,

    fragments,etc • Don’t forget to cancel threads API or Coroutines if they reference a view (or any short live object) • Use structured concurrency • Avoid to pass “this” to an object which lives longer than “this” • Use performance monitoring tools • There are memory leaks that you won't solve, but don't hesitate to report them.