9

I know there is a lot of discussion about android bitmap images out of memory but I was wondering if someone could explain it to me..

Currently in my app I have an activity which lists image thumbnail (low quality) and when I click an image it opens a new activity to view the image full screen. In my 2nd activity class I have:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
bm = BitmapFactory.decodeFile(myImagePath, options);

I then put this into an ImageView to display it. This works and displays my image to its full quality. However if i click back and then click to see that image again (and repeat this 6 times) .. on the 6th time opening the image (activity2) I get an out of memory error saying Heap size=6919KB, Allocated=3125KB, Bitmap Size = 25848KB!

How is bitmap size that big? I assumed it may be creating new instances all the time so I then decided to put a method in my 2nd activity for when the back key is pressed..and in this method I set my bitmap=null and also did System.gc() to clear the garbage collector BUT this did not fix the problem. I still get an out of memory error on the 6th time of clicking on the thumbnail to view the image in full resolution

Can anyone explain why? Thanks

Mr X
  • 171
  • 1
  • 3
  • 7

2 Answers2

16

There is some great information from android that explains it all in detail, and how to overcome this problem here.

Each pixel is 4 Bytes. 6M Pixel = 24MBs

One photo can use up all the Memory.

Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the camera on the Galaxy Nexus takes photos up to 2592x1936 pixels (5 megapixels). If the bitmap configuration used is ARGB_8888 (the default from the Android 2.3 onward) then loading this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some devices.

Again I point you to this great link I found from another SO Question that has tutorials of how to properly over come the problem.

IAmGroot
  • 13,760
  • 18
  • 84
  • 154
  • How to handle this problem with Picasso or Universal Image Loader? I'm using those libs and still getting OOM very quickly. – Sagar Panwala Mar 30 '16 at 08:27
  • @SagarPanwala [This might be useful](http://stackoverflow.com/questions/30011106/download-image-and-resize-to-avoid-oom-errors-picasso-fit-distorts-image). Consider also that you are using too much memory elsewhere. [It might not be Picasso itself](https://github.com/square/picasso/issues/1153) – IAmGroot Mar 30 '16 at 08:37
  • but I have this requirement in the main screen and I'm just running the app and scrolling it and it crashes. I have viewpager with 5 images (width and height = screenwidth) as ListView item. – Sagar Panwala Mar 30 '16 at 09:39
  • @SagarPanwala Are you sure that the height and width are screen width. Make sure you are only loading images as required, and disposing of it when not visible. You are best asking your own question, with details/code/images so the community can help :) – IAmGroot Mar 30 '16 at 13:50
2

inSample size should be set so that the image is scaled to the size of the display area (1 = full size) unless there is some reason you think you need all the bits of the image, so 2 would = 1/2 scale 4 1/4 scale etc.

Also try bm.recycle() when you are finished with the bitmap before using =null

Update

Look at the second answer what does recycle do unless you have already tried that and it didn't work. I have done similar things with loading images and never run out of memory, that's not proof that it will work for you, but it's a best practice as far as I can tell.

Community
  • 1
  • 1
Idistic
  • 6,281
  • 2
  • 28
  • 38
  • As far as i'm aware bm.recycle(); does absolutely nothing. I understand the scale sizes and yes I need my image to be full scale. I even created onDestory method and called the garbage collector, called finish(); and set my view instance and variables to null..etc and it still crashed – Mr X Jul 13 '11 at 17:19
  • So your image h/w is <= display size or are you saying you need to manipulate the bits? As to .recylce doing nothing that's not what the docs say --- void recycle() Free the native object associated with this bitmap, and clear the reference to the pixel data. So did you actually try .recyle() as well? – Idistic Jul 13 '11 at 17:27
  • @dronyx see me comment above and modified answer – Idistic Jul 13 '11 at 17:36
  • 3
    recycle DOES free the memory used by a Bitmap, and is very important. – David Snabel-Caunt Jul 13 '11 at 17:36
  • 3
    I have fixed the OOM exception now. Basically Android doesn't garbage collect when destroying an activity. So when you restart that activity and in this case i'm loading up a bitmap image..the memory heap will get big quickly and eventually run out of memory. To fix it, I added the following to my onDestory method : bm.recycle; customImageView.setImageDrawable(null); System.gc(); – Mr X Jul 13 '11 at 17:38
  • @dronyx, yes you need to remove all references before GC will work of course, when you are talking about the application context I am assuming you used an activity context that wasn't disposed of properly previously? Next time maybe provide a bit more code so we can see this all. Anyway glad it is working for you now, would still use .recycle to optimize this though. – Idistic Jul 13 '11 at 17:43
  • Yes I agree. Basically for anyone reading you need to remember to do recycle bitmap, then null bitmap, then garbage collect - all in the onDestroy method – Mr X Jul 13 '11 at 17:52
  • @ Mr X, it does not have to be on the OnDestory, right? It can be anywhere after you are done with the image – Snake Dec 17 '13 at 19:25