Locating and remedying cause of large heap size
I'm trying to work out why my app is using so much memory. I often see it using between 15 and 18MB, which is substantially higher than I'd expect. I took a look at the heap size via DDMS and saw this:
That looked a tad suspicous because my app doesn't deal with large images at all. In fact the total sum of the drawables in my app is about 250KB. So I created a heap dump and used MAT to locate where all this memory was going. byte arrays were by far the greatest consumer, so I drilled down and noticed the following:
I have absolutely no idea why sPreloadedDrawables is responsible for such a high retained heap size. I also have no idea of how to identify the root cause, or how to 'fix' it.
Where should I go from here? My app works mostly in the background via services which don't deal with image data at all. I do have Activities that the user may choose to use, but again, they use small drawables which don't explain such a large heap size. I also checked for any nasty occurrences of Activity leaks etc, but didn't locate any.
EDIT: I noticed that the heap size is substantially lower when run in the emulator. This is quite confusing. :/
The system will preload the default system resources, this is independent of your app resources, things like standard Drawables for check boxes and radio buttons. 10.5MB does seem large but there are a lot of default system resources and the Images are bigger once stored in memory. Preloading is not new, but the size of preload could be larger in ICS. Display density probably plays a part in this along with simply the addition of more system Drawables preloaded in ICS.
There is currently no way to reduce the memory held by the sPreloadedDrawables
It is unfortunate that there isn't a way to clear this after the app process is spawned for apps (especially games) that don't use most of the system Drawables. In this case though the large size of the preload resources seems to have been a bug with a specific release (or handset port) of ICS. It is otherwise normally a small amount of memory, so I doubt it would ever be necessary to have such a mechanism to reduce the preload memory use.
If you are running out of memory as a result of this cache then I'd probably file a bug report to Google.
You can trace through the resource preload process here if you are interested in more internal details. ZygoteInit.preloadResources