Grindr Ansgar Lin Sep 7, 2019

OOM Bitmap Resource Analysis and Optimization

Article Summary

Ansgar Lin from Grindr Engineering found a single placeholder image consuming 8.3MB of memory at runtime. On devices with only 16-32MB Java heap, that's a recipe for constant crashes.

Most Android OOM crashes trace back to oversized Bitmaps lurking in memory. Lin walks through using Android Studio Profiler to hunt down memory hogs, explaining how Android 8+ changed where pixel data lives (native heap vs Java heap), and evaluating real solutions beyond the usual advice.

Key Takeaways

Critical Insight

Switching from raster images to VectorDrawable cut runtime memory usage by 93%, but comes with performance tradeoffs that require case-by-case evaluation.

The article reveals a critical caching behavior in older Android versions that could quietly tank your VectorDrawable performance.

About This Article

Problem

Grindr Engineering ran into a problem where Android 8+ stores Bitmap pixel data in the native heap instead of the Java heap. This made memory profiling work differently depending on the OS version, which made it harder to figure out what was actually causing OOM crashes.

Solution

Ansgar Lin used Android Studio's Memory Profiler to see where the data was being stored. He then looked at VectorDrawable as a way to replace the raster image assets. The fix only needed config changes like setting vectorDrawables.useSupportLibrary = true and using app:srcCompat in the XML.

Impact

VectorDrawableCompat used just 2KB on devices before Android 21, compared to 8.3MB for the original placeholder. The images still looked good and they didn't need to do runtime scaling or caching anymore.