Unusual side of memory problems in Android

The storm has settled after the frantic days leading up to the conference and now that I had time to reflect upon the Linux Session’s events and my application I was given an unexpected task. Apart from posting on this blog and actually providing the App for conference-goers I also managed to get my teacher of Embedded and Mobile Systems to let me pass the labs with this project. However, unbeknownst to me he also planned a little surprise for me. He tasked me with creating a software design document, a specification of sorts for the project. It is available on github and it took quite a bit of time to write but unfortunately it is only available in Polish and I can’t really be bothered to translate it. I’m so sorry :(. Still, even though it was taxing and took all of the time I had available for the project, it’s not really so interesting to talk about. I will instead tell you a story of one weird bug with my appp I had during the conference.

OutOfMemoryException and where to find it

Whenever you launch your application (or process to be exact) Android allocates some of heap memory available for you device to it. It is usually a pretty small amount of memory, some 10 megabytes most probably. As soon as your application requires more memory for its objects it requests more heap size. However if your application requests more memory that is assignable to one process on your device you encounter a problem.
OutOfMemoryException is thrown and your app crashes. There are two common causes of such situation:

1) If it happens after some time in your application, after navigating through many screens or showing a lot of data several times over it is usually a memory leak. Debugging and fighting those is a topic for another time and I will write a post about it.

2) Second, less common issue is a large, fast spike in the memory allocation that makes it hard for the OS to react quickly enough and free sufficient memory for the app not to crash. This is the one I experienced.

Fighting OOME

The kind of memory allocation problem I described is not that hard to debug because more often than not it comes down to a misuse of assets. The particular problem I faced crashed the app only on certain devices and only in one place in the application. It crashed while entering MiddleParty Fragment. I realised I made several mistakes with the backgrounds of the fullscreen dialogs of MiddleParty info.

Using Android Monitor I discovered the exact place, where memory allocation happened really quick and managed to narrow it down to several factors:
– Assets not resized for every screen densities -> always loading the full-sized .png into RAM
– Picasso didn’t call .fit() so it didn’t resize the assets on its own.
– All the backgrounds being loaded in the begining instead of only when needed.
All these issues added up to the app crashing under some conditions.

The fix was quick and the bug was patched up on the Google Play some 25 minutes later. I properly down-scaled the assets so that much less memory was required for every .png file. I also called .fit() on Picasso so that the properly resized assets were cached and so it was faster to launch in the future. I also delegated the loading of fullscreen backgrounds to another Thread which made the app more responsive in those situations.

Leave a comment

Your email address will not be published. Required fields are marked *