Memory leaks and how to find them

Mohamed Magdi
MDroid
Published in
4 min readMar 13, 2017

--

You just finished your shiny new app and everything looks great. Suddenly your app’s UI lags, it’s getting slower and images are taking more time to load. Then comes the dreaded moment where you get a crash dialog and you find out you’ve hit an `java.lang.OutOfMemoryException`

OutOfMemoryExceptions are hard to find since they, usually, happen in places not related to the cause of the memory problem. This usually is due to one of the following:

  • Your app is a memory intensive app, and you’re not managing your memory well. (Out of scope for this article)
  • Your app starts leaking memory until the android runtime decided it’s enough and killed your app. (Which is what we’re discussing here)

Let’s start with understanding how memory management works in Android. As you know Android have two runtime environments ART(Android Runtime) for devices running Android 5.0+ and Dalvik(process virtual machine) for devices running older Android API versions.

In both runtime environments, memory heaps are segmented to spaces according to type of allocation and how the GC events will be organized by the system. When a new object is allocated based on which android runtime used and taking care of these characteristics, it is allocated in the best way.

It is important to notice that each space has a specific size. When you allocate more objects and a memory space starts to be filled the system starts to run GC events to free as much space as it can. if GC failed to allocate more space the system starts to increase the space size to accept the new allocations. And here we face the first problem when your app starts having a lot of allocations the GC events start to be more frequent to free space and that’s when you start feeling that your app UI is slower than normal. That means the main thread will spend more time with the GC and will skip more frames.

As result of that Choreographer will start logging how many frames it skipped. Its normal for the Choreographer to skip frames but when this happens a lot then you will feel the lag in your application UI.

Plus you may also notice many changes in your memory monitor in Android Studio. Every drop in the graph represents a GC event.

When the memory space is filled and GC events can’t de-allocate any of your objects ( most likely because of leaked objects ). Here you will get the known crash ‘Java.lang.OutOfMemoryException’. In that case, its hard to find the reason of the crash using stack trace, as the object failed to be allocated is not the leaking object.

Now we have a fair understanding of how the memory allocation works in Android, lets take a look into how to detect leaks and avoid them from the beginning.

1. Add LeakCanary to your application.

LeakCanary is a powerful library that will help ease your development cycle by telling you when an activity or fragment starts to leak memory. It keeps track of all the allocated memory using weak references and will notify you when you leak an object.

Add leak canary to your dependencies.
Setup leak canary to your application.

2. Use Android studio memory monitor

Android studio has some tools to help you analyzing your memory usage. The memory tool gives you 3 actions:

  • Initiate GC
  • Dump java heap
  • Start allocation tracking.

Nice trick you can use is to create an empty Activity initiate GC event then navigate to this empty activity then dump java heap and check what objects did you leak from your activity. The analyzer can detect leaked activities and duplicated strings.

--

--