Tuesday, October 16, 2012

All Hail Explicit Garbage Collection Calls (and the logcat)!

For the last few weeks we've been working on a mobile app that requires handling of large image files. We started developing it as a multi-platform app via PhoneGap/Cordova; however, the Android version just wouldn't work when it came to loading large images from the "gallery" and then turning them into a base-64 string for posting to a server. Looking through the logcat


source: rootzwiki forum


we realized that there was a FATAL OutOfMemoryError every time we tried to load large pictures into the app. After some digging around the Interwebz, StackOverflow and the blog of Simon Mac Donald (one of PhoneGap's main contributors) we surmised that this problem could only be addressed at the native level. So, we started building a  small proof-of-concept Android app to see how we could address this issue. After couple days of fiddling with different ideas, we were having the same problem caused by Android's inefficient Bitmap handling that made the app crash and burn when loading and encoding a large (8MP) image. Facing having to get down and dirty with multi-threading or AsyncTask (so we could offload the memory intensive parts), in a moment of lucidity (actually: desperation), I suggested my co-worker we try issuing explicit garbage collection calls. So, after adding a dash of System.gc()to the critical parts of our code and loading it up into the device (because the damn emulator is too damn slow, but that's a different rant) I was expecting it to have very little effect, if any, but it was worth the shot. But, to our bafflement, not only did it work, but also it actually fixed the OutOfMemoryError issues we were having completely. 

So, the main take-aways are: Android has memory-inefficient Bitmap handling. Possible memory inefficiency in the Base64 class. Explicit garbage collection calls are the bee's knees!

P.S.: After the fact I looked around to see if using explicit garbage collection calls was a no-no, but on the contrary, it seems it is widely used and necessary for memory-intensive activities. Also, as per documentation, explicit garbage collection calls in the Dalvik VM don't force garbage collection; they just "nudge" the GC to look your app's way for possible memory cleanup.

No comments:

Post a Comment