Gokhan Arik February 2016

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!

Answers


Xerillio February 2016

I'm not sure about the resolution differences, but the difference between the used memory and the size of the file is because an image in the JPG format (as many other formats) is compressed (see the wiki for how). When you then load it into memory, it is no longer compressed, as it's used to draw every single pixel on the screen.


CommonsWare February 2016

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.


Sam Dozor February 2016

The default and highest quality configuration for a Bitmap is ARGB_8888, which will use 4 bytes per pixel. Since your image is being scaled to 2625*4669, that's:

2625*4669*4 bytes = 49024500 bytes

http://developer.android.com/reference/android/graphics/Bitmap.Config.html

Post Status

Asked in February 2016
Viewed 2,497 times
Voted 9
Answered 3 times

Search




Leave an answer