Search code examples
javaandroidperformanceandroid-memory

Why does my 160kb app background become 49 MB at run time?


I decided to investigate my app's memory usage and I looked at Android Studio's Memory Monitor and my memory usage was around 68 MB. It looks too high to me.

enter image description here

I opened memory allocator and started tracking from the beginning of the application. I saw that there is a 49 MB allocation of a NonMovableArray, which is a Bitmap.

enter image description here

I debugged the application and found out that it was the background I was using. The lines below are from PhoneWindow.java file, that's where Android assigns the background to the screen I believe. The background object had a size of 49 MB and 2625x4669 resolution.

I have no overdraw in my app, and I have a single background that is applied to entire theme.

I have a background drawable in drawable folder in JPG format with 750x1,334 resolution.

PhoneWindow.java

if (mBackgroundResource != 0) {
    background = getContext().getDrawable(mBackgroundResource);
} else {
    background = mBackgroundDrawable;
}

I am testing this on a Motorola Nexus 6 device which has 560 density with a resolution of 1440 x 2560.

There are two points I don't understand.

  1. If the device has a resolution of 1440x2560, why would my background get converted to 2625x4669?
  2. Even if this conversion is the best scenario for the app, how come a 160 KB file would end up being 49 MB?

If you guys can explain this to me that would be great. Thanks!


Solution

  • If the device has a resolution of 1440x2560, why would my background get converted to 2625x4669?

    You put the image in res/drawable/. This is not a good choice, as that is a synonym for res/drawable-mdpi/. Hence, Android is resampling your image, thinking that you were aiming for -mdpi devices (~160dpi), so the image is about the same physical size on the Nexus 6 (3.5x the density).

    Whether res/drawable-nodpi/ or res/drawable-anydpi/ is the right choice depends a bit on your alternative versions of this resource, though either will probably work.

    how come a 160 KB file would end up being 49 MB?

    The image takes up 160KB on disk. The memory footprint is the decoded image. That will be the image resolution (post-resampling) times 4 bytes/pixel for ARGB_8888 images. 2625x4669x4 ~= 49MB.