6

I'm having severe memory issues in my application [1]. In order to investigate this, I took heapdumps of my app at different states. I saw that some bitmaps were taking huge amounts of memory. I wrote a small tool [2] that decodes the byte arrays to Windows bitmap files (.bmp), so that I can see the bitmaps and compare them to the files I have in my res/drawable folder.

What I discovered is that all my files are upsampled twice.
I first checked with the biggest one had: a byte array buffer of more than 9MB in the heap, which was decoded to be a nice 1920x1280 picture, while the original one was a 960x640 png file.
I tried with the second biggest, over 3MB, which once decoded showed a nice 754x1200 picture, the original size was... guess what? A nice 377x600 jpg file.

What gives?

I have enabled HW acceleration in my Android Manifest file (though I'm not sure I really need it, I'm just using some basic views and activities).
I'm running stock Android 4.0.2 on a GSM Galaxy Nexus (yakju). I'm receiving feedback from my testers that the issue is present on their 4.0.3 Nexus S, though I couldn't check their heap dumps yet.

I'm trying to save memory here, if Android doubles everything, no wonder the app crashes quickly because the heap usage gets too high (around 64MB in my case). I hope there's a reason and a way around it.

References:

  1. OutOfMemoryError when loading activities
  2. How to actually see a Bitmap taken from an Android heap dump
trincot
  • 317,000
  • 35
  • 244
  • 286
Benoit Duffez
  • 11,839
  • 12
  • 77
  • 125
  • You should post your code for when you are setting the sample size and decoding the image. This should give more information about this behavior. It could possibly be a ICS problem. – JoxTraex Mar 08 '12 at 23:16
  • I am just inflating several ImageViews. Check the link [1] if you need to see some code, everything's there. – Benoit Duffez Mar 08 '12 at 23:21

1 Answers1

7

When you put images in res/drawable, Android will assume they have a dpi of 160, i.e. it is the same as putting them in res/drawable-mdpi. Galaxy Nexus is an xhdpi device, i.e. it has a (generalized) dpi of 320. To compensate for the high resolution display, Android will upsample the images with 200%.

The solution is simple, just put the images in res/drawable-xhdpi instead. Then the declared dpi of the images will match the display you run on, and Android will not perform any scaling of the images.

Please refer to http://developer.android.com/guide/practices/screens_support.html for more info.

Martin Nordholts
  • 10,338
  • 2
  • 39
  • 43
  • OK, I see. The problem is that the app I am developing contains hundreds of pictures, and the customer won't like when I'll say that he needs to do all of them in another resolution. I'll find an easy way, but thank you so much for helping me! Moving the big pictures to drawable-xhdpi removed all memory issues, I'm below 40MB where before that I was over 60MB. Thank you. – Benoit Duffez Mar 09 '12 at 08:05