5

So I get this:

'01-01 20:37:34.859: E/dalvikvm-heap(19921): Out of memory on a 6471856-byte allocation.'

When trying to assign a bunch of variables to memory. I'm assigning 24 variables like these:

mElements.add(new ShopElement(getResources(),R.drawable.shop_starter, b1X , b1Y,true,1,"red",true,5,checkLocked(0)));

And one of these:

bNumbers = new Bitmap[] {Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h0)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h1)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h2)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h3)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h4)
        ,65,65,true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h5)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h6)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h7)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h8)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h9)
        , 65,65, true),
        Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.time)
                , 50,50, true)};

But before I can get through #16 of the 24 elements I'm created, it crashes on certain phones.

I have a Galaxy S2 and it runs fine, but on the S3 and other phones it crashes.

I will be happy to provide more information upon request.

I've searched this error before, tried to apply solutions, and looked through the "Displaying Bitmaps Efficiently" thing, but nothing seems to help.

What spins my head is that it works on the S2, but not the S3. Shouldn't the S3 exceed the S2 in every way?

I am using a global BitmapFactory.Options to draw all my bitmaps I set the options as follows:

Global.opts = new BitmapFactory.Options();
    Global.opts.inDither=false;                     
    Global.opts.inPurgeable=true;                  
    Global.opts.inInputShareable=true;              
    Global.opts.inTempStorage=new byte[16 * 1024]; 
  • 3
    Of course. You put so many Bitmaps into memory. Try to refine your logic. – Raptor Jan 02 '13 at 04:11
  • 1
    My guess is the phones it crashes on have less memory available then the phone it doesn't crash on. Resizing images typically is very expensive memory wise, perhaps chunk it out so the garbage collection has time to work. – Matthew Jan 02 '13 at 04:11
  • I'm not experienced in "chunking things out". Does that mean that I should separate assigning groups variables by frames? –  Jan 02 '13 at 04:17
  • 1
    Jeez! Are you *really* loading 6.5++ MB images to your handset???? 50K - reasonable. 1MB - large. 6.5MB - Fuggedabouddit! IMHO... – paulsm4 Jan 02 '13 at 04:22
  • Apparently, I am. I haven't calculated the total size of the images, but apparently. –  Jan 02 '13 at 04:24
  • So I'm trying to chunk things out, and it still isn't working. I do a chunk, and then the next frame, I do another chunk. I do five of these chunks, but it still crashes. Smaller chunks, I guess? –  Jan 02 '13 at 04:44
  • What does the `ShopElement` look like? Does each instance create one of those `bNumbers` arrays also? Just showing the constructor with the drawable Id passed in doesn't allude much to what the object does with that Id. – devunwired Jan 02 '13 at 05:15
  • Each 'ShopElement' boils down to a scaled bitmap. –  Jan 02 '13 at 06:07

3 Answers3

8

Simply you are trying to access more memory then you have. So solution would be to either increase memory or use only available memory.

Three suggestions to do so.

1) If you are using BitmapFactory.Options and still error persist then it means that you are not using proper configuration of it for the given image. Just Make sure that Heap size is sufficient.

 BitmapFactory.Options opts=new BitmapFactory.Options();
        opts.inDither=false;                     //Disable Dithering mode
        opts.inSampleSize = 8;                    // scale image upto 1/8 of the original image.
        opts.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
        opts.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
        opts.inTempStorage=new byte[16 * 1024]; //you can increase this value as per your need.

You can increase the inTempStorage size to make it work or sample the image by using inSampleSize attribute. For more on sampling, you can refer this link.

Try playing with different options. It should work.

2) You can also increase you App's overall Heap size by using android:largeHeap="true" atribute in manifest file but this will not work on any pre Honeycomb devices. On pre 2.3 devices, you can use the VMRuntime class.

3) If you want to programmatically detect you Heap size and want to change it according to the need then you can follow this link.

Community
  • 1
  • 1
Moin Ahmed
  • 2,858
  • 19
  • 33
  • I edited the question to include a sample of how i use Options. I'll try increasing the heap size –  Jan 02 '13 at 06:16
  • Well that doesn't work. Whenever I try to apply 'android:largeHeap="true"' it just gives me a red X and says "no resource identifier found" –  Jan 02 '13 at 06:23
  • Including "inSampleSize" seemed to work, but now everything looks horrible. But it works so you get the point. I'll play around with the sample size and detecting heap size and adjust it dynamically for now, until I can find a better way of loading my 34 bitmaps –  Jan 02 '13 at 07:05
  • ALSO: use the smallest bitmaps possible. You'll use less memory. But more important, your app should run faster, and be that much more attractive to use. IMHO.. – paulsm4 Jan 02 '13 at 17:05
2

The error clearly says that you are trying to use more memory. This directly points to the image sizes. So, you need to resize your images to use lesser memory. One which can be used for this reason is BitmapFactory.Option. Or else go with manually resizing your images take care that it suit all your needs. Just for the sake of explaining things,

Heap size is the amount of memory allocated to an application to execute. The heap size for android applications are determined by the device RAM. For example if the device has RAM of 179 MB, the android applications will only get the heap size of 18MB.

Find about it more here. more on how to Load Large Bitmaps Efficiently is found here.

I have a Galaxy S2 and it runs fine, but on the S3 and other phones it crashes

Checkout the RAM size of devices you mentioned.

Vinay
  • 6,797
  • 4
  • 29
  • 49
  • I am using BitmapFactory.Option –  Jan 02 '13 at 04:33
  • [inSampleSize](http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize) try using this. – Vinay Jan 02 '13 at 06:16
  • Thank you for suggesting inSampleSize. It works, but I'm giving credit to CCMinds since he put it in his answer. I hope you don't mind. You have a bunch of points and medals anyway –  Jan 02 '13 at 07:07
1

In Android Memory Management, every app has a Maximum Heap memory it can use , once the app uses more than the heap memory Android OS will automatically kill's the app. So only you are getting "Out of Memory Exception"..

To solve this you can go for NDK concept of Android.. Since the heap concept is for the SDK part..

i.e,

you can make a App uses more than 300MB (if available) of RAM using NDK but not possible in SDK

Sudarshan
  • 1,227
  • 3
  • 24
  • 35